diff --git a/.github/update.log b/.github/update.log index 0ccee38ac2..08f7daa49c 100644 --- a/.github/update.log +++ b/.github/update.log @@ -653,3 +653,4 @@ Update On Fri May 17 20:29:52 CEST 2024 Update On Sat May 18 20:30:29 CEST 2024 Update On Sun May 19 20:28:25 CEST 2024 Update On Mon May 20 20:29:32 CEST 2024 +Update On Tue May 21 20:28:45 CEST 2024 diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff b/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff new file mode 100644 index 0000000000..2c68233358 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff @@ -0,0 +1,54 @@ +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +index 06e684c7116b4..b311a5c74684b 100644 +--- a/src/syscall/exec_windows.go ++++ b/src/syscall/exec_windows.go +@@ -319,17 +319,6 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle + } + } + +- 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 { +@@ -338,15 +327,7 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- 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) ++ err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -377,14 +358,6 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle + + 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 \ No newline at end of file diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff b/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff new file mode 100644 index 0000000000..ca41ec317e --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff @@ -0,0 +1,158 @@ +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +index 62738e2cb1a7d..d0dcc7cc71fc0 100644 +--- a/src/crypto/rand/rand.go ++++ b/src/crypto/rand/rand.go +@@ -15,7 +15,7 @@ import "io" + // 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 RtlGenRandom API. ++// On Windows systems, Reader uses the ProcessPrng 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 +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +index 6c0655c72b692..7380f1f0f1e6e 100644 +--- a/src/crypto/rand/rand_windows.go ++++ b/src/crypto/rand/rand_windows.go +@@ -15,11 +15,8 @@ func init() { Reader = &rngReader{} } + + type rngReader struct{} + +-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 { ++func (r *rngReader) Read(b []byte) (int, error) { ++ if err := windows.ProcessPrng(b); err != nil { + return 0, err + } + return len(b), nil +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +index ab4ad2ec64108..5854ca60b5cef 100644 +--- a/src/internal/syscall/windows/syscall_windows.go ++++ b/src/internal/syscall/windows/syscall_windows.go +@@ -373,7 +373,7 @@ func ErrorLoadingGetTempPath2() error { + //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 RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 ++//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +index e3f6d8d2a2208..5a587ad4f146c 100644 +--- a/src/internal/syscall/windows/zsyscall_windows.go ++++ b/src/internal/syscall/windows/zsyscall_windows.go +@@ -37,13 +37,14 @@ func errnoErr(e syscall.Errno) error { + } + + var ( +- 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")) ++ 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")) + + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") +@@ -55,7 +56,7 @@ var ( + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") ++ procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -179,12 +180,12 @@ func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32 + return + } + +-func RtlGenRandom(buf []byte) (err error) { ++func ProcessPrng(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +index 8ca8d7790909e..3772a864b2ff4 100644 +--- a/src/runtime/os_windows.go ++++ b/src/runtime/os_windows.go +@@ -127,15 +127,8 @@ var ( + _WriteFile, + _ 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 ++ // Use ProcessPrng to generate cryptographically random data. ++ _ProcessPrng stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -151,11 +144,11 @@ var ( + ) + + var ( +- advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '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} ++ 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 +@@ -251,11 +244,11 @@ func windowsLoadSystemLib(name []uint16) uintptr { + } + + func loadOptionalSyscalls() { +- a32 := windowsLoadSystemLib(advapi32dll[:]) +- if a32 == 0 { +- throw("advapi32.dll not found") ++ bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) ++ if bcryptPrimitives == 0 { ++ throw("bcryptprimitives.dll not found") + } +- _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) + + n32 := windowsLoadSystemLib(ntdlldll[:]) + if n32 == 0 { +@@ -531,7 +524,7 @@ func osinit() { + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n \ No newline at end of file diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff b/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff new file mode 100644 index 0000000000..c1fc5f6d2d --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff @@ -0,0 +1,162 @@ +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +index ab8656cbbf343..28c49cc6de7e7 100644 +--- a/src/net/hook_windows.go ++++ b/src/net/hook_windows.go +@@ -14,7 +14,6 @@ var ( + testHookDialChannel = func() { time.Sleep(time.Millisecond) } // see golang.org/issue/5349 + + // 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 +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +index 0197feb3f199a..967ce6795aedb 100644 +--- a/src/net/internal/socktest/main_test.go ++++ b/src/net/internal/socktest/main_test.go +@@ -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 ++//go:build !js && !plan9 && !wasip1 && !windows + + package socktest_test + +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +deleted file mode 100644 +index df1cb97784b51..0000000000000 +--- a/src/net/internal/socktest/main_windows_test.go ++++ /dev/null +@@ -1,22 +0,0 @@ +-// 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 +-} +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +index 8c1c862f33c9b..1c42e5c7f34b7 100644 +--- a/src/net/internal/socktest/sys_windows.go ++++ b/src/net/internal/socktest/sys_windows.go +@@ -9,38 +9,6 @@ import ( + "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) +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +index 07f21b72eb1fc..bc024c0bbd82d 100644 +--- a/src/net/main_windows_test.go ++++ b/src/net/main_windows_test.go +@@ -8,7 +8,6 @@ import "internal/poll" + + var ( + // Placeholders for saving original socket system calls. +- origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -18,7 +17,6 @@ var ( + ) + + func installTestHooks() { +- socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -28,7 +26,6 @@ func installTestHooks() { + } + + func uninstallTestHooks() { +- socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +index fa11c7af2e727..5540135a2c43e 100644 +--- a/src/net/sock_windows.go ++++ b/src/net/sock_windows.go +@@ -19,21 +19,6 @@ func maxListenerBacklog() int { + 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) + } +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +index 0a93bc0a80d4e..06e684c7116b4 100644 +--- a/src/syscall/exec_windows.go ++++ b/src/syscall/exec_windows.go +@@ -14,6 +14,7 @@ import ( + "unsafe" + ) + ++// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed \ No newline at end of file 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 df320d29b0..42023755e1 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 @@ -1,6 +1,10 @@ name: Build on: workflow_dispatch: + inputs: + version: + description: "Tag version to release" + required: true push: paths-ignore: - "docs/**" @@ -13,9 +17,8 @@ on: pull_request_target: branches: - Alpha - concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: "${{ github.workflow }}-${{ github.ref }}" cancel-in-progress: true env: @@ -64,6 +67,13 @@ jobs: - { goos: android, goarch: arm, ndk: armv7a-linux-androideabi34, output: armv7 } - { goos: android, goarch: arm64, ndk: aarch64-linux-android34, output: arm64-v8 } + # Go 1.21 can revert commit `9e4385` to work on Windows 7 + # https://github.com/golang/go/issues/64622#issuecomment-1847475161 + # (OR we can just use golang1.21.4 which unneeded any patch) + - { goos: windows, goarch: '386', output: '386-go121', goversion: '1.21' } + - { goos: windows, goarch: amd64, goamd64: v1, output: amd64-compatible-go121, goversion: '1.21' } + - { goos: windows, goarch: amd64, goamd64: v3, output: amd64-go121, goversion: '1.21' } + # Go 1.20 is the last release that will run on any release of Windows 7, 8, Server 2008 and Server 2012. Go 1.21 will require at least Windows 10 or Server 2016. - { goos: windows, goarch: '386', output: '386-go120', goversion: '1.20' } - { goos: windows, goarch: amd64, goamd64: v1, output: amd64-compatible-go120, goversion: '1.20' } @@ -94,28 +104,50 @@ jobs: with: go-version: ${{ matrix.jobs.goversion }} - - name: Set up Go1.21 loongarch abi1 + - name: Set up Go1.22 loongarch abi1 if: ${{ matrix.jobs.goarch == 'loong64' && matrix.jobs.abi == '1' }} run: | - wget -q https://github.com/xishang0128/loongarch64-golang/releases/download/1.21.5/go1.21.5.linux-amd64-abi1.tar.gz - sudo tar zxf go1.21.5.linux-amd64-abi1.tar.gz -C /usr/local + wget -q https://github.com/xishang0128/loongarch64-golang/releases/download/1.22.0/go1.22.0.linux-amd64-abi1.tar.gz + sudo tar zxf go1.22.0.linux-amd64-abi1.tar.gz -C /usr/local echo "/usr/local/go/bin" >> $GITHUB_PATH - - name: Set up Go1.21 loongarch abi2 + - name: Set up Go1.22 loongarch abi2 if: ${{ matrix.jobs.goarch == 'loong64' && matrix.jobs.abi == '2' }} run: | - wget -q https://github.com/xishang0128/loongarch64-golang/releases/download/1.21.5/go1.21.5.linux-amd64-abi2.tar.gz - sudo tar zxf go1.21.5.linux-amd64-abi2.tar.gz -C /usr/local + wget -q https://github.com/xishang0128/loongarch64-golang/releases/download/1.22.0/go1.22.0.linux-amd64-abi2.tar.gz + sudo tar zxf go1.22.0.linux-amd64-abi2.tar.gz -C /usr/local echo "/usr/local/go/bin" >> $GITHUB_PATH + # 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 + # 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" + - name: Revert Golang1.22 commit for Windows7/8 + if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '' }} + run: | + cd $(go env GOROOT) + patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/693def151adff1af707d82d28f55dba81ceb08e1.diff + patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/7c1157f9544922e96945196b47b95664b1e39108.diff + patch --verbose -R -p 1 < $GITHUB_WORKSPACE/.github/patch_go122/48042aa09c2f878c4faa576948b07fe625c4707a.diff + + # 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: | + cd $(go env GOROOT) + curl https://github.com/golang/go/commit/9e43850a3298a9b8b1162ba0033d4c53f8637571.diff | patch --verbose -R -p 1 + - name: Set variables - if: ${{github.ref_name=='Alpha'}} - run: echo "VERSION=alpha-$(git rev-parse --short HEAD)" >> $GITHUB_ENV + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }} + run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV shell: bash - name: Set variables - if: ${{github.ref_name=='' || github.ref_type=='tag'}} - run: echo "VERSION=$(git describe --tags)" >> $GITHUB_ENV + if: ${{ github.event_name != 'workflow_dispatch' && github.ref_name == 'Alpha' }} + run: echo "VERSION=alpha-$(git rev-parse --short HEAD)" >> $GITHUB_ENV shell: bash - name: Set Time Variable @@ -238,7 +270,7 @@ jobs: - name: Archive production artifacts uses: actions/upload-artifact@v4 with: - name: ${{ matrix.jobs.goos }}-${{ matrix.jobs.output }} + name: "${{ matrix.jobs.goos }}-${{ matrix.jobs.output }}" path: | mihomo*.gz mihomo*.deb @@ -248,7 +280,7 @@ jobs: Upload-Prerelease: permissions: write-all - if: ${{ github.ref_type == 'branch' && !startsWith(github.event_name, 'pull_request') }} + if: ${{ github.event_name != 'workflow_dispatch' && github.ref_type == 'branch' && !startsWith(github.event_name, 'pull_request') }} needs: [build] runs-on: ubuntu-latest steps: @@ -299,44 +331,62 @@ jobs: Upload-Release: permissions: write-all - if: ${{ github.ref_type=='tag' }} + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }} needs: [build] runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 + - name: Checkout + uses: actions/checkout@v4 + with: + ref: Meta + fetch-depth: '0' + fetch-tags: 'true' - - name: Get tags - run: | - echo "CURRENTVERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - git fetch --tags - echo "PREVERSION=$(git describe --tags --abbrev=0 HEAD^)" >> $GITHUB_ENV + - name: Get tags + run: | + echo "CURRENTVERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + git fetch --tags + echo "PREVERSION=$(git describe --tags --abbrev=0 HEAD)" >> $GITHUB_ENV - - name: Generate release notes - run: | - cp ./.github/genReleaseNote.sh ./ - bash ./genReleaseNote.sh -v ${PREVERSION}...${CURRENTVERSION} - rm ./genReleaseNote.sh + - name: Merge Alpha branch into Meta + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git fetch origin Alpha:Alpha + git merge Alpha + git push origin Meta + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/download-artifact@v4 - with: - path: bin/ - merge-multiple: true + - name: Tag the commit + run: | + git tag ${{ github.event.inputs.version }} + git push origin ${{ github.event.inputs.version }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Display structure of downloaded files - run: ls -R - working-directory: bin - - - name: Upload Release - uses: softprops/action-gh-release@v1 - if: ${{ success() }} - with: - tag_name: ${{ github.ref_name }} - files: bin/* - generate_release_notes: true - body_path: release.md + - name: Generate release notes + run: | + cp ./.github/genReleaseNote.sh ./ + bash ./genReleaseNote.sh -v ${PREVERSION}...${CURRENTVERSION} + rm ./genReleaseNote.sh + + - uses: actions/download-artifact@v4 + with: + path: bin/ + merge-multiple: true + + - name: Display structure of downloaded files + run: ls -R + working-directory: bin + + - name: Upload Release + uses: softprops/action-gh-release@v2 + if: ${{ success() }} + with: + tag_name: ${{ github.event.inputs.version }} + files: bin/* + body_path: release.md Docker: if: ${{ !startsWith(github.event_name, 'pull_request') }} @@ -365,20 +415,35 @@ jobs: uses: docker/setup-buildx-action@v3 with: version: latest - + # Extract metadata (tags, labels) for Docker # https://github.com/docker/metadata-action - name: Extract Docker metadata - id: meta + if: ${{ github.event_name != 'workflow_dispatch' }} + id: meta_alpha uses: docker/metadata-action@v5 with: - images: ${{ env.REGISTRY }}/${{ github.repository }} - + images: '${{ env.REGISTRY }}/${{ github.repository }}' + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }} + id: meta_release + uses: docker/metadata-action@v5 + with: + images: '${{ env.REGISTRY }}/${{ github.repository }}' + tags: | + ${{ github.event.inputs.version }} + flavor: | + latest=true + labels: org.opencontainers.image.version=${{ github.event.inputs.version }} + - name: Show files run: | ls . ls bin/ - + - name: login to docker REGISTRY uses: docker/login-action@v3 with: @@ -389,7 +454,7 @@ jobs: # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action - name: Build and push Docker image - id: build-and-push + if: ${{ github.event_name != 'workflow_dispatch' }} uses: docker/build-push-action@v5 with: context: . @@ -400,5 +465,20 @@ jobs: linux/amd64 linux/arm64 linux/arm/v7 - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta_alpha.outputs.tags }} + labels: ${{ steps.meta_alpha.outputs.labels }} + + - name: Build and push Docker image + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }} + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: ${{ github.event_name != 'pull_request' }} + platforms: | + linux/386 + linux/amd64 + linux/arm64 + linux/arm/v7 + tags: ${{ steps.meta_release.outputs.tags }} + labels: ${{ steps.meta_release.outputs.labels }} \ No newline at end of file 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 dbf3db6eb9..8136827a09 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 @@ -2,6 +2,7 @@ package adapter import ( "context" + "crypto/tls" "encoding/json" "fmt" "net" @@ -14,6 +15,7 @@ import ( "github.com/metacubex/mihomo/common/atomic" "github.com/metacubex/mihomo/common/queue" "github.com/metacubex/mihomo/common/utils" + "github.com/metacubex/mihomo/component/ca" "github.com/metacubex/mihomo/component/dialer" C "github.com/metacubex/mihomo/constant" "github.com/puzpuzpuz/xsync/v3" @@ -230,6 +232,7 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, + TLSClientConfig: ca.GetGlobalTLSConfig(&tls.Config{}), } client := http.Client{ diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go index 714c4a7d68..88fb84566b 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go @@ -273,6 +273,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) { if opts.TLS { v2rayOption.TLS = true v2rayOption.SkipCertVerify = opts.SkipCertVerify + v2rayOption.Fingerprint = opts.Fingerprint } } else if option.Plugin == shadowtls.Mode { obfsMode = shadowtls.Mode diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go index c1c981ced9..7d5a7224e1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go @@ -179,6 +179,7 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M tlsOpts := mihomoVMess.TLSConfig{ Host: host, SkipCertVerify: v.option.SkipCertVerify, + FingerPrint: v.option.Fingerprint, NextProtos: []string{"h2"}, ClientFingerprint: v.option.ClientFingerprint, Reality: v.realityConfig, @@ -208,6 +209,7 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M tlsOpts := &mihomoVMess.TLSConfig{ Host: host, SkipCertVerify: v.option.SkipCertVerify, + FingerPrint: v.option.Fingerprint, ClientFingerprint: v.option.ClientFingerprint, Reality: v.realityConfig, NextProtos: v.option.ALPN, 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 b39ee3a659..69fbb61799 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 @@ -48,7 +48,7 @@ type GroupBaseOption struct { func NewGroupBase(opt GroupBaseOption) *GroupBase { var excludeFilterReg *regexp2.Regexp if opt.excludeFilter != "" { - excludeFilterReg = regexp2.MustCompile(opt.excludeFilter, 0) + excludeFilterReg = regexp2.MustCompile(opt.excludeFilter, regexp2.None) } var excludeTypeArray []string if opt.excludeType != "" { @@ -58,7 +58,7 @@ func NewGroupBase(opt GroupBaseOption) *GroupBase { var filterRegs []*regexp2.Regexp if opt.filter != "" { for _, filter := range strings.Split(opt.filter, "`") { - filterReg := regexp2.MustCompile(filter, 0) + filterReg := regexp2.MustCompile(filter, regexp2.None) filterRegs = append(filterRegs, filterReg) } } @@ -126,7 +126,7 @@ func (gb *GroupBase) GetProxies(touch bool) []C.Proxy { for _, filterReg := range gb.filterRegs { for _, p := range proxies { name := p.Name() - if mat, _ := filterReg.FindStringMatch(name); mat != nil { + if mat, _ := filterReg.MatchString(name); mat { if _, ok := proxiesSet[name]; !ok { proxiesSet[name] = struct{}{} newProxies = append(newProxies, p) @@ -150,7 +150,7 @@ func (gb *GroupBase) GetProxies(touch bool) []C.Proxy { for _, filterReg := range gb.filterRegs { for _, p := range proxies { name := p.Name() - if mat, _ := filterReg.FindStringMatch(name); mat != nil { + if mat, _ := filterReg.MatchString(name); mat { if _, ok := proxiesSet[name]; !ok { proxiesSet[name] = struct{}{} newProxies = append(newProxies, p) @@ -191,7 +191,7 @@ func (gb *GroupBase) GetProxies(touch bool) []C.Proxy { var newProxies []C.Proxy for _, p := range proxies { name := p.Name() - if mat, _ := gb.excludeFilterReg.FindStringMatch(name); mat != nil { + if mat, _ := gb.excludeFilterReg.MatchString(name); mat { continue } newProxies = append(newProxies, p) 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 876c92fa32..67dc104dfb 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 @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "github.com/dlclark/regexp2" + "github.com/metacubex/mihomo/adapter/outbound" "github.com/metacubex/mihomo/adapter/provider" "github.com/metacubex/mihomo/common/structure" @@ -70,7 +72,22 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide groupOption.Use = append(groupOption.Use, AllProviders...) } if groupOption.IncludeAllProxies { - groupOption.Proxies = append(groupOption.Proxies, AllProxies...) + if groupOption.Filter != "" { + var filterRegs []*regexp2.Regexp + for _, filter := range strings.Split(groupOption.Filter, "`") { + filterReg := regexp2.MustCompile(filter, regexp2.None) + filterRegs = append(filterRegs, filterReg) + } + for _, p := range AllProxies { + for _, filterReg := range filterRegs { + if mat, _ := filterReg.MatchString(p); mat { + groupOption.Proxies = append(groupOption.Proxies, p) + } + } + } + } else { + groupOption.Proxies = append(groupOption.Proxies, AllProxies...) + } } if len(groupOption.Proxies) == 0 && len(groupOption.Use) == 0 { diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/provider/healthcheck.go b/clash-meta-android/core/src/foss/golang/clash/adapter/provider/healthcheck.go index bfbcf8d904..8b5e833851 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/provider/healthcheck.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/provider/healthcheck.go @@ -181,14 +181,14 @@ func (hc *HealthCheck) execute(b *batch.Batch[bool], url, uid string, option *ex filters = append(filters, filter) } - filterReg = regexp2.MustCompile(strings.Join(filters, "|"), 0) + filterReg = regexp2.MustCompile(strings.Join(filters, "|"), regexp2.None) } } for _, proxy := range hc.proxies { // skip proxies that do not require health check if filterReg != nil { - if match, _ := filterReg.FindStringMatch(proxy.Name()); match == nil { + if match, _ := filterReg.MatchString(proxy.Name()); !match { continue } } 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 a40a50ec44..daef017c95 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 @@ -169,7 +169,7 @@ func stopProxyProvider(pd *ProxySetProvider) { } func NewProxySetProvider(name string, interval time.Duration, filter string, excludeFilter string, excludeType string, dialerProxy string, override OverrideSchema, vehicle types.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) { - excludeFilterReg, err := regexp2.Compile(excludeFilter, 0) + excludeFilterReg, err := regexp2.Compile(excludeFilter, regexp2.None) if err != nil { return nil, fmt.Errorf("invalid excludeFilter regex: %w", err) } @@ -180,7 +180,7 @@ func NewProxySetProvider(name string, interval time.Duration, filter string, exc var filterRegs []*regexp2.Regexp for _, filter := range strings.Split(filter, "`") { - filterReg, err := regexp2.Compile(filter, 0) + filterReg, err := regexp2.Compile(filter, regexp2.None) if err != nil { return nil, fmt.Errorf("invalid filter regex: %w", err) } @@ -356,12 +356,12 @@ func proxiesParseAndFilter(filter string, excludeFilter string, excludeTypeArray continue } if len(excludeFilter) > 0 { - if mat, _ := excludeFilterReg.FindStringMatch(name); mat != nil { + if mat, _ := excludeFilterReg.MatchString(name); mat { continue } } if len(filter) > 0 { - if mat, _ := filterReg.FindStringMatch(name); mat == nil { + if mat, _ := filterReg.MatchString(name); !mat { continue } } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/ca/config.go b/clash-meta-android/core/src/foss/golang/clash/component/ca/config.go index d56809a16e..9d002db639 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/ca/config.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/ca/config.go @@ -67,9 +67,6 @@ func ResetCertificate() { } func getCertPool() *x509.CertPool { - if len(trustCerts) == 0 { - return nil - } if globalCertPool == nil { mutex.Lock() defer mutex.Unlock() diff --git a/clash-meta-android/core/src/foss/golang/clash/component/ca/fix_windows.go b/clash-meta-android/core/src/foss/golang/clash/component/ca/fix_windows.go new file mode 100644 index 0000000000..42511791ef --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/ca/fix_windows.go @@ -0,0 +1,14 @@ +package ca + +import ( + "github.com/metacubex/mihomo/constant/features" +) + +func init() { + // crypto/x509: certificate validation in Windows fails to validate IP in SAN + // https://github.com/golang/go/issues/37176 + // As far as I can tell this is still the case on most older versions of Windows (but seems to be fixed in 10) + if features.WindowsMajorVersion < 10 && len(_CaCertificates) > 0 { + DisableSystemCa = true + } +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go b/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go index 8fb5a0a649..c21e638e4e 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go @@ -164,7 +164,7 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po if opt.mpTcp { setMultiPathTCP(dialer) } - if opt.tfo { + if opt.tfo && !DisableTFO { return dialTFO(ctx, *dialer, network, address) } return dialer.DialContext(ctx, network, address) diff --git a/clash-meta-android/core/src/foss/golang/clash/component/dialer/tfo.go b/clash-meta-android/core/src/foss/golang/clash/component/dialer/tfo.go index 228e96898b..76fe94d021 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/dialer/tfo.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/dialer/tfo.go @@ -9,6 +9,8 @@ import ( "github.com/metacubex/tfo-go" ) +var DisableTFO = false + type tfoConn struct { net.Conn closed bool diff --git a/clash-meta-android/core/src/foss/golang/clash/component/dialer/tfo_windows.go b/clash-meta-android/core/src/foss/golang/clash/component/dialer/tfo_windows.go new file mode 100644 index 0000000000..632661186c --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/dialer/tfo_windows.go @@ -0,0 +1,11 @@ +package dialer + +import "github.com/metacubex/mihomo/constant/features" + +func init() { + // According to MSDN, this option is available since Windows 10, 1607 + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596(v=vs.85).aspx + if features.WindowsMajorVersion < 10 || (features.WindowsMajorVersion == 10 && features.WindowsBuildNumber < 14393) { + DisableTFO = true + } +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/resolver/host.go b/clash-meta-android/core/src/foss/golang/clash/component/resolver/host.go index 7e299a099d..53fa5924b8 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/resolver/host.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/resolver/host.go @@ -9,6 +9,7 @@ import ( _ "unsafe" "github.com/metacubex/mihomo/common/utils" + "github.com/metacubex/mihomo/component/resolver/hosts" "github.com/metacubex/mihomo/component/trie" "github.com/zhangyunhao116/fastrand" ) @@ -28,11 +29,6 @@ func NewHosts(hosts *trie.DomainTrie[HostValue]) Hosts { } } -// lookupStaticHost looks up the addresses and the canonical name for the given host from /etc/hosts. -// -//go:linkname lookupStaticHost net.lookupStaticHost -func lookupStaticHost(host string) ([]string, string) - // Return the search result and whether to match the parameter `isDomain` func (h *Hosts) Search(domain string, isDomain bool) (*HostValue, bool) { if value := h.DomainTrie.Search(domain); value != nil { @@ -56,7 +52,7 @@ func (h *Hosts) Search(domain string, isDomain bool) (*HostValue, bool) { } if !isDomain && !DisableSystemHosts && UseSystemHosts { - addr, _ := lookupStaticHost(domain) + addr, _ := hosts.LookupStaticHost(domain) if hostValue, err := NewHostValue(addr); err == nil { return &hostValue, true } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/resolver/hosts/hosts.go b/clash-meta-android/core/src/foss/golang/clash/component/resolver/hosts/hosts.go new file mode 100644 index 0000000000..780ebb2479 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/resolver/hosts/hosts.go @@ -0,0 +1,309 @@ +package hosts + +// this file copy and modify from golang's std net/hosts.go + +import ( + "errors" + "io" + "io/fs" + "net/netip" + "os" + "strings" + "sync" + "time" +) + +var hostsFilePath = "/etc/hosts" + +const cacheMaxAge = 5 * time.Second + +func parseLiteralIP(addr string) string { + ip, err := netip.ParseAddr(addr) + if err != nil { + return "" + } + return ip.String() +} + +type byName struct { + addrs []string + canonicalName string +} + +// hosts contains known host entries. +var hosts struct { + sync.Mutex + + // Key for the list of literal IP addresses must be a host + // name. It would be part of DNS labels, a FQDN or an absolute + // FQDN. + // For now the key is converted to lower case for convenience. + byName map[string]byName + + // Key for the list of host names must be a literal IP address + // including IPv6 address with zone identifier. + // We don't support old-classful IP address notation. + byAddr map[string][]string + + expire time.Time + path string + mtime time.Time + size int64 +} + +func readHosts() { + now := time.Now() + hp := hostsFilePath + + if now.Before(hosts.expire) && hosts.path == hp && len(hosts.byName) > 0 { + return + } + mtime, size, err := stat(hp) + if err == nil && hosts.path == hp && hosts.mtime.Equal(mtime) && hosts.size == size { + hosts.expire = now.Add(cacheMaxAge) + return + } + + hs := make(map[string]byName) + is := make(map[string][]string) + + file, err := open(hp) + if err != nil { + if !errors.Is(err, fs.ErrNotExist) && !errors.Is(err, fs.ErrPermission) { + return + } + } + + if file != nil { + defer file.close() + for line, ok := file.readLine(); ok; line, ok = file.readLine() { + if i := strings.IndexByte(line, '#'); i >= 0 { + // Discard comments. + line = line[0:i] + } + f := getFields(line) + if len(f) < 2 { + continue + } + addr := parseLiteralIP(f[0]) + if addr == "" { + continue + } + + var canonical string + for i := 1; i < len(f); i++ { + name := absDomainName(f[i]) + h := []byte(f[i]) + lowerASCIIBytes(h) + key := absDomainName(string(h)) + + if i == 1 { + canonical = key + } + + is[addr] = append(is[addr], name) + + if v, ok := hs[key]; ok { + hs[key] = byName{ + addrs: append(v.addrs, addr), + canonicalName: v.canonicalName, + } + continue + } + + hs[key] = byName{ + addrs: []string{addr}, + canonicalName: canonical, + } + } + } + } + // Update the data cache. + hosts.expire = now.Add(cacheMaxAge) + hosts.path = hp + hosts.byName = hs + hosts.byAddr = is + hosts.mtime = mtime + hosts.size = size +} + +// LookupStaticHost looks up the addresses and the canonical name for the given host from /etc/hosts. +func LookupStaticHost(host string) ([]string, string) { + hosts.Lock() + defer hosts.Unlock() + readHosts() + if len(hosts.byName) != 0 { + if hasUpperCase(host) { + lowerHost := []byte(host) + lowerASCIIBytes(lowerHost) + host = string(lowerHost) + } + if byName, ok := hosts.byName[absDomainName(host)]; ok { + ipsCp := make([]string, len(byName.addrs)) + copy(ipsCp, byName.addrs) + return ipsCp, byName.canonicalName + } + } + return nil, "" +} + +// LookupStaticAddr looks up the hosts for the given address from /etc/hosts. +func LookupStaticAddr(addr string) []string { + hosts.Lock() + defer hosts.Unlock() + readHosts() + addr = parseLiteralIP(addr) + if addr == "" { + return nil + } + if len(hosts.byAddr) != 0 { + if hosts, ok := hosts.byAddr[addr]; ok { + hostsCp := make([]string, len(hosts)) + copy(hostsCp, hosts) + return hostsCp + } + } + return nil +} + +func stat(name string) (mtime time.Time, size int64, err error) { + st, err := os.Stat(name) + if err != nil { + return time.Time{}, 0, err + } + return st.ModTime(), st.Size(), nil +} + +type file struct { + file *os.File + data []byte + atEOF bool +} + +func (f *file) close() { f.file.Close() } + +func (f *file) getLineFromData() (s string, ok bool) { + data := f.data + i := 0 + for i = 0; i < len(data); i++ { + if data[i] == '\n' { + s = string(data[0:i]) + ok = true + // move data + i++ + n := len(data) - i + copy(data[0:], data[i:]) + f.data = data[0:n] + return + } + } + if f.atEOF && len(f.data) > 0 { + // EOF, return all we have + s = string(data) + f.data = f.data[0:0] + ok = true + } + return +} + +func (f *file) readLine() (s string, ok bool) { + if s, ok = f.getLineFromData(); ok { + return + } + if len(f.data) < cap(f.data) { + ln := len(f.data) + n, err := io.ReadFull(f.file, f.data[ln:cap(f.data)]) + if n >= 0 { + f.data = f.data[0 : ln+n] + } + if err == io.EOF || err == io.ErrUnexpectedEOF { + f.atEOF = true + } + } + s, ok = f.getLineFromData() + return +} + +func (f *file) stat() (mtime time.Time, size int64, err error) { + st, err := f.file.Stat() + if err != nil { + return time.Time{}, 0, err + } + return st.ModTime(), st.Size(), nil +} + +func open(name string) (*file, error) { + fd, err := os.Open(name) + if err != nil { + return nil, err + } + return &file{fd, make([]byte, 0, 64*1024), false}, nil +} + +func getFields(s string) []string { return splitAtBytes(s, " \r\t\n") } + +// Count occurrences in s of any bytes in t. +func countAnyByte(s string, t string) int { + n := 0 + for i := 0; i < len(s); i++ { + if strings.IndexByte(t, s[i]) >= 0 { + n++ + } + } + return n +} + +// Split s at any bytes in t. +func splitAtBytes(s string, t string) []string { + a := make([]string, 1+countAnyByte(s, t)) + n := 0 + last := 0 + for i := 0; i < len(s); i++ { + if strings.IndexByte(t, s[i]) >= 0 { + if last < i { + a[n] = s[last:i] + n++ + } + last = i + 1 + } + } + if last < len(s) { + a[n] = s[last:] + n++ + } + return a[0:n] +} + +// lowerASCIIBytes makes x ASCII lowercase in-place. +func lowerASCIIBytes(x []byte) { + for i, b := range x { + if 'A' <= b && b <= 'Z' { + x[i] += 'a' - 'A' + } + } +} + +// hasUpperCase tells whether the given string contains at least one upper-case. +func hasUpperCase(s string) bool { + for i := range s { + if 'A' <= s[i] && s[i] <= 'Z' { + return true + } + } + return false +} + +// absDomainName returns an absolute domain name which ends with a +// trailing dot to match pure Go reverse resolver and all other lookup +// routines. +// See golang.org/issue/12189. +// But we don't want to add dots for local names from /etc/hosts. +// It's hard to tell so we settle on the heuristic that names without dots +// (like "localhost" or "myhost") do not get trailing dots, but any other +// names do. +func absDomainName(s string) string { + if strings.IndexByte(s, '.') != -1 && s[len(s)-1] != '.' { + s += "." + } + return s +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/resolver/hosts/hosts_windows.go b/clash-meta-android/core/src/foss/golang/clash/component/resolver/hosts/hosts_windows.go new file mode 100644 index 0000000000..8ad76e0ac0 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/resolver/hosts/hosts_windows.go @@ -0,0 +1,13 @@ +package hosts + +// this file copy and modify from golang's std net/hook_windows.go + +import ( + "golang.org/x/sys/windows" +) + +func init() { + if dir, err := windows.GetSystemDirectory(); err == nil { + hostsFilePath = dir + "/Drivers/etc/hosts" + } +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/sniffer/dispatcher.go b/clash-meta-android/core/src/foss/golang/clash/component/sniffer/dispatcher.go index 96e9272c5b..97bf162969 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/sniffer/dispatcher.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/sniffer/dispatcher.go @@ -116,14 +116,13 @@ func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata } func (sd *SnifferDispatcher) replaceDomain(metadata *C.Metadata, host string, overrideDest bool) { - // show log early, since the following code may mutate `metadata.Host` - log.Debugln("[Sniffer] Sniff %s [%s]-->[%s] success, replace domain [%s]-->[%s]", - metadata.NetWork, - metadata.SourceDetail(), - metadata.RemoteAddress(), - metadata.Host, host) metadata.SniffHost = host if overrideDest { + log.Debugln("[Sniffer] Sniff %s [%s]-->[%s] success, replace domain [%s]-->[%s]", + metadata.NetWork, + metadata.SourceDetail(), + metadata.RemoteAddress(), + metadata.Host, host) metadata.Host = host } metadata.DNSMode = C.DNSNormal diff --git a/clash-meta-android/core/src/foss/golang/clash/component/tls/reality.go b/clash-meta-android/core/src/foss/golang/clash/component/tls/reality.go index 687ef1ef9c..48da3e92ac 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/tls/reality.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/tls/reality.go @@ -16,16 +16,13 @@ import ( "errors" "net" "net/http" - "reflect" "strings" "time" - "unsafe" - "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/ntp" - utls "github.com/sagernet/utls" + utls "github.com/metacubex/utls" "github.com/zhangyunhao116/fastrand" "golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/hkdf" @@ -39,9 +36,6 @@ type RealityConfig struct { ShortID [RealityMaxShortIDLen]byte } -//go:linkname aesgcmPreferred crypto/tls.aesgcmPreferred -func aesgcmPreferred(ciphers []uint16) bool - func GetRealityConn(ctx context.Context, conn net.Conn, ClientFingerprint string, tlsConfig *tls.Config, realityConfig *RealityConfig) (net.Conn, error) { retry := 0 for fingerprint, exists := GetFingerprint(ClientFingerprint); exists; retry++ { @@ -102,7 +96,7 @@ func GetRealityConn(ctx context.Context, conn net.Conn, ClientFingerprint string return nil, err } var aeadCipher cipher.AEAD - if aesgcmPreferred(hello.CipherSuites) { + if utls.AesgcmPreferred(hello.CipherSuites) { aesBlock, _ := aes.NewCipher(authKey) aeadCipher, _ = cipher.NewGCM(aesBlock) } else { @@ -139,7 +133,10 @@ func realityClientFallback(uConn net.Conn, serverName string, fingerprint utls.C }, }, } - request, _ := http.NewRequest("GET", "https://"+serverName, nil) + request, err := http.NewRequest("GET", "https://"+serverName, nil) + if err != nil { + return + } request.Header.Set("User-Agent", fingerprint.Client) request.AddCookie(&http.Cookie{Name: "padding", Value: strings.Repeat("0", fastrand.Intn(32)+30)}) response, err := client.Do(request) @@ -159,11 +156,12 @@ type realityVerifier struct { verified bool } -var pOffset = utils.MustOK(reflect.TypeOf((*utls.Conn)(nil)).Elem().FieldByName("peerCertificates")).Offset +//var pOffset = utils.MustOK(reflect.TypeOf((*utls.Conn)(nil)).Elem().FieldByName("peerCertificates")).Offset func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { //p, _ := reflect.TypeOf(c.Conn).Elem().FieldByName("peerCertificates") - certs := *(*[]*x509.Certificate)(unsafe.Add(unsafe.Pointer(c.Conn), pOffset)) + //certs := *(*[]*x509.Certificate)(unsafe.Add(unsafe.Pointer(c.Conn), pOffset)) + certs := c.Conn.PeerCertificates() if pub, ok := certs[0].PublicKey.(ed25519.PublicKey); ok { h := hmac.New(sha512.New, c.authKey) h.Write(pub) diff --git a/clash-meta-android/core/src/foss/golang/clash/component/tls/utls.go b/clash-meta-android/core/src/foss/golang/clash/component/tls/utls.go index 3063fc55f6..31733e50a4 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/tls/utls.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/tls/utls.go @@ -6,8 +6,8 @@ import ( "github.com/metacubex/mihomo/log" + utls "github.com/metacubex/utls" "github.com/mroth/weightedrand/v2" - utls "github.com/sagernet/utls" ) type UConn struct { diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/updater/updater.go b/clash-meta-android/core/src/foss/golang/clash/component/updater/update_core.go similarity index 99% rename from clash-meta-android/core/src/foss/golang/clash/hub/updater/updater.go rename to clash-meta-android/core/src/foss/golang/clash/component/updater/update_core.go index df5da3f4d1..0070fbb110 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/updater/updater.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/updater/update_core.go @@ -67,7 +67,7 @@ func (e *updateError) Error() string { // Update performs the auto-updater. It returns an error if the updater failed. // If firstRun is true, it assumes the configuration file doesn't exist. -func Update(execPath string) (err error) { +func UpdateCore(execPath string) (err error) { mu.Lock() defer mu.Unlock() diff --git a/clash-meta-android/core/src/foss/golang/clash/config/update_geo.go b/clash-meta-android/core/src/foss/golang/clash/component/updater/update_geo.go similarity index 52% rename from clash-meta-android/core/src/foss/golang/clash/config/update_geo.go rename to clash-meta-android/core/src/foss/golang/clash/component/updater/update_geo.go index 43cac25c8d..b07cd31587 100644 --- a/clash-meta-android/core/src/foss/golang/clash/config/update_geo.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/updater/update_geo.go @@ -1,18 +1,27 @@ -package config +package updater import ( + "errors" "fmt" + "os" "runtime" + "time" + "github.com/metacubex/mihomo/common/atomic" "github.com/metacubex/mihomo/component/geodata" _ "github.com/metacubex/mihomo/component/geodata/standard" "github.com/metacubex/mihomo/component/mmdb" C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/log" "github.com/oschwald/maxminddb-golang" ) -func UpdateGeoDatabases() error { +var ( + UpdatingGeo atomic.Bool +) + +func updateGeoDatabases() error { defer runtime.GC() geoLoader, err := geodata.GetGeoDataLoader("standard") if err != nil { @@ -88,3 +97,80 @@ func UpdateGeoDatabases() error { return nil } + +var ErrGetDatabaseUpdateSkip = errors.New("GEO database is updating, skip") + +func UpdateGeoDatabases() error { + log.Infoln("[GEO] Start updating GEO database") + + if UpdatingGeo.Load() { + return ErrGetDatabaseUpdateSkip + } + + UpdatingGeo.Store(true) + defer UpdatingGeo.Store(false) + + log.Infoln("[GEO] Updating GEO database") + + if err := updateGeoDatabases(); err != nil { + log.Errorln("[GEO] update GEO database error: %s", err.Error()) + return err + } + + return nil +} + +func getUpdateTime() (err error, time time.Time) { + var fileInfo os.FileInfo + if C.GeodataMode { + fileInfo, err = os.Stat(C.Path.GeoIP()) + if err != nil { + return err, time + } + } else { + fileInfo, err = os.Stat(C.Path.MMDB()) + if err != nil { + return err, time + } + } + + return nil, fileInfo.ModTime() +} + +func RegisterGeoUpdater(onSuccess func()) { + if C.GeoUpdateInterval <= 0 { + log.Errorln("[GEO] Invalid update interval: %d", C.GeoUpdateInterval) + return + } + + go func() { + ticker := time.NewTicker(time.Duration(C.GeoUpdateInterval) * time.Hour) + defer ticker.Stop() + + err, lastUpdate := getUpdateTime() + if err != nil { + log.Errorln("[GEO] Get GEO database update time error: %s", err.Error()) + return + } + + log.Infoln("[GEO] last update time %s", lastUpdate) + if lastUpdate.Add(time.Duration(C.GeoUpdateInterval) * time.Hour).Before(time.Now()) { + log.Infoln("[GEO] Database has not been updated for %v, update now", time.Duration(C.GeoUpdateInterval)*time.Hour) + if err := UpdateGeoDatabases(); err != nil { + log.Errorln("[GEO] Failed to update GEO database: %s", err.Error()) + return + } else { + onSuccess() + } + } + + for range ticker.C { + log.Infoln("[GEO] updating database every %d hours", C.GeoUpdateInterval) + if err := UpdateGeoDatabases(); err != nil { + log.Errorln("[GEO] Failed to update GEO database: %s", err.Error()) + } else { + onSuccess() + } + } + }() +} diff --git a/clash-meta-android/core/src/foss/golang/clash/config/update_ui.go b/clash-meta-android/core/src/foss/golang/clash/component/updater/update_ui.go similarity index 97% rename from clash-meta-android/core/src/foss/golang/clash/config/update_ui.go rename to clash-meta-android/core/src/foss/golang/clash/component/updater/update_ui.go index cff1d6d7bd..85452ba550 100644 --- a/clash-meta-android/core/src/foss/golang/clash/config/update_ui.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/updater/update_ui.go @@ -1,4 +1,4 @@ -package config +package updater import ( "archive/zip" @@ -29,7 +29,7 @@ func UpdateUI() error { xdMutex.Lock() defer xdMutex.Unlock() - err := prepare() + err := prepare_ui() if err != nil { return err } @@ -64,7 +64,7 @@ func UpdateUI() error { return nil } -func prepare() error { +func prepare_ui() error { if ExternalUIPath == "" || ExternalUIURL == "" { return ErrIncompleteConf } diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/updater/limitedreader.go b/clash-meta-android/core/src/foss/golang/clash/component/updater/utils.go similarity index 70% rename from clash-meta-android/core/src/foss/golang/clash/hub/updater/limitedreader.go rename to clash-meta-android/core/src/foss/golang/clash/component/updater/utils.go index c31db601d0..0eecfc6cdc 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/updater/limitedreader.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/updater/utils.go @@ -1,12 +1,35 @@ package updater import ( + "context" "fmt" "io" + "net/http" + "os" + "time" + + mihomoHttp "github.com/metacubex/mihomo/component/http" + C "github.com/metacubex/mihomo/constant" "golang.org/x/exp/constraints" ) +func downloadForBytes(url string) ([]byte, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*90) + defer cancel() + resp, err := mihomoHttp.HttpRequest(ctx, url, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return io.ReadAll(resp.Body) +} + +func saveFile(bytes []byte, path string) error { + return os.WriteFile(path, bytes, 0o644) +} + // LimitReachedError records the limit and the operation that caused it. type LimitReachedError struct { Limit int64 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 b76c40ff8c..9bc0afc824 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 @@ -28,6 +28,7 @@ import ( SNIFF "github.com/metacubex/mihomo/component/sniffer" tlsC "github.com/metacubex/mihomo/component/tls" "github.com/metacubex/mihomo/component/trie" + "github.com/metacubex/mihomo/component/updater" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/constant/features" providerTypes "github.com/metacubex/mihomo/constant/provider" @@ -640,28 +641,28 @@ func parseGeneral(cfg *RawConfig) (*General, error) { N.KeepAliveInterval = time.Duration(cfg.KeepAliveInterval) * time.Second } - ExternalUIPath = cfg.ExternalUI + updater.ExternalUIPath = cfg.ExternalUI // checkout externalUI exist - if ExternalUIPath != "" { - ExternalUIPath = C.Path.Resolve(ExternalUIPath) - if _, err := os.Stat(ExternalUIPath); os.IsNotExist(err) { + if updater.ExternalUIPath != "" { + updater.ExternalUIPath = C.Path.Resolve(updater.ExternalUIPath) + if _, err := os.Stat(updater.ExternalUIPath); os.IsNotExist(err) { defaultUIpath := path.Join(C.Path.HomeDir(), "ui") - log.Warnln("external-ui: %s does not exist, creating folder in %s", ExternalUIPath, defaultUIpath) + log.Warnln("external-ui: %s does not exist, creating folder in %s", updater.ExternalUIPath, defaultUIpath) if err := os.MkdirAll(defaultUIpath, os.ModePerm); err != nil { return nil, err } - ExternalUIPath = defaultUIpath + updater.ExternalUIPath = defaultUIpath cfg.ExternalUI = defaultUIpath } } // checkout UIpath/name exist if cfg.ExternalUIName != "" { - ExternalUIName = cfg.ExternalUIName + updater.ExternalUIName = cfg.ExternalUIName } else { - ExternalUIFolder = ExternalUIPath + updater.ExternalUIFolder = updater.ExternalUIPath } if cfg.ExternalUIURL != "" { - ExternalUIURL = cfg.ExternalUIURL + updater.ExternalUIURL = cfg.ExternalUIURL } cfg.Tun.RedirectToTun = cfg.EBpf.RedirectToTun @@ -927,7 +928,7 @@ func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[s l := len(rule) - if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" || ruleName == "DOMAIN-REGEX" { + if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" || ruleName == "DOMAIN-REGEX" || ruleName == "PROCESS-NAME-REGEX" || ruleName == "PROCESS-PATH-REGEX" { target = rule[l-1] payload = strings.Join(rule[1:l-1], ",") } else { 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 66bf3441f2..f87fb34131 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 @@ -1,38 +1,15 @@ package config import ( - "context" "fmt" - "io" "net" - "net/http" "net/netip" - "os" "strings" - "time" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/structure" - mihomoHttp "github.com/metacubex/mihomo/component/http" - C "github.com/metacubex/mihomo/constant" ) -func downloadForBytes(url string) ([]byte, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*90) - defer cancel() - resp, err := mihomoHttp.HttpRequest(ctx, url, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - return io.ReadAll(resp.Body) -} - -func saveFile(bytes []byte, path string) error { - return os.WriteFile(path, bytes, 0o644) -} - func trimArr(arr []string) (r []string) { for _, e := range arr { r = append(r, strings.Trim(e, " ")) diff --git a/clash-meta-android/core/src/foss/golang/clash/constant/features/version.go b/clash-meta-android/core/src/foss/golang/clash/constant/features/version.go new file mode 100644 index 0000000000..1710e218eb --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/constant/features/version.go @@ -0,0 +1,5 @@ +package features + +var WindowsMajorVersion uint32 +var WindowsMinorVersion uint32 +var WindowsBuildNumber uint32 diff --git a/clash-meta-android/core/src/foss/golang/clash/constant/features/version_windows.go b/clash-meta-android/core/src/foss/golang/clash/constant/features/version_windows.go new file mode 100644 index 0000000000..192df950fe --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/constant/features/version_windows.go @@ -0,0 +1,10 @@ +package features + +import "golang.org/x/sys/windows" + +func init() { + version := windows.RtlGetVersion() + WindowsMajorVersion = version.MajorVersion + WindowsMinorVersion = version.MinorVersion + WindowsBuildNumber = version.MinorVersion +} diff --git a/clash-meta-android/core/src/foss/golang/clash/constant/rule.go b/clash-meta-android/core/src/foss/golang/clash/constant/rule.go index 8fdd75a6c0..161c200a60 100644 --- a/clash-meta-android/core/src/foss/golang/clash/constant/rule.go +++ b/clash-meta-android/core/src/foss/golang/clash/constant/rule.go @@ -22,8 +22,10 @@ const ( InUser InName InType - Process + ProcessName ProcessPath + ProcessNameRegex + ProcessPathRegex RuleSet Network Uid @@ -76,10 +78,14 @@ func (rt RuleType) String() string { return "InName" case InType: return "InType" - case Process: - return "Process" + case ProcessName: + return "ProcessName" case ProcessPath: return "ProcessPath" + case ProcessNameRegex: + return "ProcessNameRegex" + case ProcessPathRegex: + return "ProcessPathRegex" case MATCH: return "Match" case RuleSet: 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 0769a21230..ad2492ffa6 100644 --- a/clash-meta-android/core/src/foss/golang/clash/go.mod +++ b/clash-meta-android/core/src/foss/golang/clash/go.mod @@ -12,21 +12,22 @@ require ( github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/cors v1.2.1 github.com/go-chi/render v1.0.3 - github.com/gobwas/ws v1.3.2 - github.com/gofrs/uuid/v5 v5.1.0 + github.com/gobwas/ws v1.4.0 + github.com/gofrs/uuid/v5 v5.2.0 github.com/insomniacslk/dhcp v0.0.0-20240419123447-f1cffa2c0c49 github.com/klauspost/cpuid/v2 v2.2.7 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/mdlayher/netlink v1.7.2 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 - github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6 - github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f + github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 + github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 github.com/metacubex/sing-shadowsocks v0.2.6 github.com/metacubex/sing-shadowsocks2 v0.2.0 - github.com/metacubex/sing-tun v0.2.6 + github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 + github.com/metacubex/utls v1.6.6 github.com/miekg/dns v1.1.59 github.com/mroth/weightedrand/v2 v2.1.0 github.com/openacid/low v0.1.21 @@ -37,24 +38,23 @@ require ( github.com/sagernet/sing v0.3.8 github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 github.com/sagernet/sing-shadowtls v0.1.4 - github.com/sagernet/utls v1.5.4 github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e github.com/samber/lo v1.39.0 - github.com/shirou/gopsutil/v3 v3.24.3 + github.com/shirou/gopsutil/v3 v3.24.4 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 github.com/wk8/go-ordered-map/v2 v2.1.8 github.com/zhangyunhao116/fastrand v0.4.0 go.uber.org/automaxprocs v1.5.3 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba - golang.org/x/crypto v0.22.0 - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f - golang.org/x/net v0.24.0 + golang.org/x/crypto v0.23.0 + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 + golang.org/x/net v0.25.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 - google.golang.org/protobuf v1.33.0 + golang.org/x/sys v0.20.0 + google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - lukechampine.com/blake3 v1.2.2 + lukechampine.com/blake3 v1.3.0 ) require ( @@ -63,7 +63,7 @@ require ( github.com/ajg/form v1.5.1 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/buger/jsonparser v1.1.1 // indirect - github.com/cloudflare/circl v1.3.6 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/ericlagergren/aegis v0.0.0-20230312195928-b4ce538b56f9 // indirect github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 // indirect @@ -105,9 +105,9 @@ require ( gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.uber.org/mock v0.4.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/tools v0.21.0 // indirect ) -replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240408015159-aa61c96df764 +replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1 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 a4d90759fb..0b4b8d3caf 100644 --- a/clash-meta-android/core/src/foss/golang/clash/go.sum +++ b/clash-meta-android/core/src/foss/golang/clash/go.sum @@ -21,8 +21,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4= github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM= -github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg= -github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -60,10 +60,10 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= 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.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q= -github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/gofrs/uuid/v5 v5.1.0 h1:S5rqVKIigghZTCBKPCw0Y+bXkn26K3TB5mvQq2Ix8dk= -github.com/gofrs/uuid/v5 v5.1.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +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.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM= +github.com/gofrs/uuid/v5 v5.2.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/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -104,24 +104,26 @@ 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-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc= github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw= -github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6 h1:qqIZ8CjoxVJP38JU9ml1RkWJfaUd7QtmOk1vl7shuRY= -github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6/go.mod h1:uXHODgJFUfUnkkCMWLd5Er6L5QY/LFRZb9LD5jyyhsk= -github.com/metacubex/sing v0.0.0-20240408015159-aa61c96df764 h1:+czGKoynxYA90YaL3NlCAIJHnlqwoUlLWgmOhdm5ZU8= -github.com/metacubex/sing v0.0.0-20240408015159-aa61c96df764/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= -github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f h1:Xyd8SHaPHS3iX3xXPnus9PsYhJIo/2e7sJ6vTKLKUm8= -github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f/go.mod h1:nfqibK+vkBtE6Ch8vYqrFTcaX4BC6TwKqNNl5rORll4= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 h1:hsQ0b2A509b6ubnLtLOcUgZ8vOb+d/667zVEJ1T2fao= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= +github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1 h1:7hDHLTmjgtRoAp59STwPQpe5Pinwi4cWex+FB3Ohvco= +github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= +github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew= +github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8= github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwVSgtE9R3QeFQ= github.com/metacubex/sing-shadowsocks v0.2.6/go.mod h1:zIkMeSnb8Mbf4hdqhw0pjzkn1d99YJ3JQm/VBg5WMTg= github.com/metacubex/sing-shadowsocks2 v0.2.0 h1:hqwT/AfI5d5UdPefIzR6onGHJfDXs5zgOM5QSgaM/9A= github.com/metacubex/sing-shadowsocks2 v0.2.0/go.mod h1:LCKF6j1P94zN8ZS+LXRK1gmYTVGB3squivBSXAFnOg8= -github.com/metacubex/sing-tun v0.2.6 h1:frc58BqnIClqcC9KcYBfVAn5bgO6WW1ANKvZW3/HYAQ= -github.com/metacubex/sing-tun v0.2.6/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= +github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec h1:K4Wq3GOdLZ/xcqwyzAt4kmYQrjokyKQ3u/Xh5Yft14U= +github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 h1:AGyIB55UfQm/0ZH0HtQO9u3l//yjtHUpjeRjjPGfGRI= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63/go.mod h1:uY+BYb0UEknLrqvbGcwi9i++KgrKxsurysgI6G1Pveo= github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 h1:as/aO/fM8nv4W4pOr9EETP6kV/Oaujk3fUNyQSJK61c= github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts= +github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8= +github.com/metacubex/utls v1.6.6/go.mod h1:+WLFUnXjcpdxXCnyX25nggw8C6YonZ8zOK2Zm/oRvdo= github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU= @@ -163,14 +165,12 @@ github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnV github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo= -github.com/sagernet/utls v1.5.4 h1:KmsEGbB2dKUtCNC+44NwAdNAqnqQ6GA4pTO0Yik56co= -github.com/sagernet/utls v1.5.4/go.mod h1:CTGxPWExIloRipK3XFpYv0OVyhO8kk3XCGW/ieyTh1s= github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e h1:iGH0RMv2FzELOFNFQtvsxH7NPmlo7X5JizEK51UCojo= github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e/go.mod h1:YbL4TKHRR6APYQv3U2RGfwLDpPYSyWz6oUlpISBEzBE= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= -github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= +github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= +github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -222,18 +222,18 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -253,25 +253,26 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= -lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= 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 653e43519b..f2cf298ad3 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 @@ -4,11 +4,11 @@ import ( "net/http" "net/netip" "path/filepath" - "sync" "github.com/metacubex/mihomo/adapter/inbound" "github.com/metacubex/mihomo/component/dialer" "github.com/metacubex/mihomo/component/resolver" + "github.com/metacubex/mihomo/component/updater" "github.com/metacubex/mihomo/config" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/hub/executor" @@ -21,11 +21,6 @@ import ( "github.com/go-chi/render" ) -var ( - updateGeoMux sync.Mutex - updatingGeo = false -) - func configRouter() http.Handler { r := chi.NewRouter() r.Get("/", getConfigs) @@ -369,40 +364,25 @@ func updateConfigs(w http.ResponseWriter, r *http.Request) { } func updateGeoDatabases(w http.ResponseWriter, r *http.Request) { - updateGeoMux.Lock() - - if updatingGeo { - updateGeoMux.Unlock() - render.Status(r, http.StatusBadRequest) - render.JSON(w, r, newError("updating...")) + err := updater.UpdateGeoDatabases() + if err != nil { + log.Errorln("[REST-API] update GEO databases failed: %v", err) + render.Status(r, http.StatusInternalServerError) + render.JSON(w, r, newError(err.Error())) return } - updatingGeo = true - updateGeoMux.Unlock() + cfg, err := executor.ParseWithPath(C.Path.Config()) + if err != nil { + log.Errorln("[REST-API] update GEO databases failed: %v", err) + render.Status(r, http.StatusInternalServerError) + render.JSON(w, r, newError("Error parsing configuration")) + return + } - go func() { - defer func() { - updatingGeo = false - }() + log.Warnln("[GEO] update GEO databases success, applying config") - log.Warnln("[REST-API] updating GEO databases...") - - if err := config.UpdateGeoDatabases(); err != nil { - log.Errorln("[REST-API] update GEO databases failed: %v", err) - return - } - - cfg, err := executor.ParseWithPath(C.Path.Config()) - if err != nil { - log.Errorln("[REST-API] update GEO databases failed: %v", err) - return - } - - log.Warnln("[REST-API] update GEO databases successful, apply config...") - - executor.ApplyConfig(cfg, false) - }() + executor.ApplyConfig(cfg, false) render.NoContent(w, r) } diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/route/upgrade.go b/clash-meta-android/core/src/foss/golang/clash/hub/route/upgrade.go index ea371798f3..db00af5c8a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/route/upgrade.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/route/upgrade.go @@ -6,8 +6,7 @@ import ( "net/http" "os" - "github.com/metacubex/mihomo/config" - "github.com/metacubex/mihomo/hub/updater" + "github.com/metacubex/mihomo/component/updater" "github.com/metacubex/mihomo/log" "github.com/go-chi/chi/v5" @@ -18,6 +17,7 @@ func upgradeRouter() http.Handler { r := chi.NewRouter() r.Post("/", upgradeCore) r.Post("/ui", updateUI) + r.Post("/geo", updateGeoDatabases) return r } @@ -31,7 +31,7 @@ func upgradeCore(w http.ResponseWriter, r *http.Request) { return } - err = updater.Update(execPath) + err = updater.UpdateCore(execPath) if err != nil { log.Warnln("%s", err) render.Status(r, http.StatusInternalServerError) @@ -48,9 +48,9 @@ func upgradeCore(w http.ResponseWriter, r *http.Request) { } func updateUI(w http.ResponseWriter, r *http.Request) { - err := config.UpdateUI() + err := updater.UpdateUI() if err != nil { - if errors.Is(err, config.ErrIncompleteConf) { + if errors.Is(err, updater.ErrIncompleteConf) { log.Warnln("%s", err) render.Status(r, http.StatusNotImplemented) render.JSON(w, r, newError(fmt.Sprintf("%s", err))) diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go b/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go index f69c2b061f..c77f92307f 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go @@ -8,7 +8,6 @@ import ( "net/http" "strings" "sync" - _ "unsafe" "github.com/metacubex/mihomo/adapter/inbound" "github.com/metacubex/mihomo/common/lru" @@ -18,11 +17,19 @@ import ( "github.com/metacubex/mihomo/log" ) -//go:linkname registerOnHitEOF net/http.registerOnHitEOF -func registerOnHitEOF(rc io.ReadCloser, fn func()) +type bodyWrapper struct { + io.ReadCloser + once sync.Once + onHitEOF func() +} -//go:linkname requestBodyRemains net/http.requestBodyRemains -func requestBodyRemains(rc io.ReadCloser) bool +func (b *bodyWrapper) Read(p []byte) (n int, err error) { + n, err = b.ReadCloser.Read(p) + if err == io.EOF && b.onHitEOF != nil { + b.once.Do(b.onHitEOF) + } + return n, err +} func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) { client := newClient(c, tunnel, additions...) @@ -100,10 +107,10 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], } }() } - if requestBodyRemains(request.Body) { - registerOnHitEOF(request.Body, startBackgroundRead) - } else { + if request.Body == nil || request.Body == http.NoBody { startBackgroundRead() + } else { + request.Body = &bodyWrapper{ReadCloser: request.Body, onHitEOF: startBackgroundRead} } resp, err = client.Do(request) if err != nil { 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 7cd9fc7235..2dc6524ee3 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 @@ -20,12 +20,14 @@ import ( tun "github.com/metacubex/sing-tun" "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/control" E "github.com/sagernet/sing/common/exceptions" F "github.com/sagernet/sing/common/format" "github.com/sagernet/sing/common/ranges" ) var InterfaceName = "Meta" +var EnforceBindInterface = false type Listener struct { closed bool @@ -263,6 +265,8 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis UDPTimeout: udpTimeout, Handler: handler, Logger: log.SingLogger, + InterfaceFinder: control.DefaultInterfaceFinder(), + EnforceBindInterface: EnforceBindInterface, } if options.FileDescriptor > 0 { diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server_windows.go b/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server_windows.go index 8da212879d..325cf09635 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server_windows.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server_windows.go @@ -3,6 +3,7 @@ package sing_tun import ( "time" + "github.com/metacubex/mihomo/constant/features" "github.com/metacubex/mihomo/log" tun "github.com/metacubex/sing-tun" @@ -27,4 +28,9 @@ func tunNew(options tun.Options) (tunIf tun.Tun, err error) { func init() { tun.TunnelType = InterfaceName + + if features.WindowsMajorVersion < 10 { + // to resolve "bind: The requested address is not valid in its context" + EnforceBindInterface = true + } } diff --git a/clash-meta-android/core/src/foss/golang/clash/main.go b/clash-meta-android/core/src/foss/golang/clash/main.go index afe9cfd244..61f1d683bd 100644 --- a/clash-meta-android/core/src/foss/golang/clash/main.go +++ b/clash-meta-android/core/src/foss/golang/clash/main.go @@ -8,10 +8,9 @@ import ( "path/filepath" "runtime" "strings" - "sync" "syscall" - "time" + "github.com/metacubex/mihomo/component/updater" "github.com/metacubex/mihomo/config" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/constant/features" @@ -32,8 +31,6 @@ var ( externalController string externalControllerUnix string secret string - updateGeoMux sync.Mutex - updatingGeo = false ) func init() { @@ -116,14 +113,17 @@ func main() { } if C.GeoAutoUpdate { - ticker := time.NewTicker(time.Duration(C.GeoUpdateInterval) * time.Hour) - - log.Infoln("[GEO] Start update GEO database every %d hours", C.GeoUpdateInterval) - go func() { - for range ticker.C { - updateGeoDatabases() + updater.RegisterGeoUpdater(func() { + cfg, err := executor.ParseWithPath(C.Path.Config()) + if err != nil { + log.Errorln("[GEO] update GEO databases failed: %v", err) + return } - }() + + log.Warnln("[GEO] update GEO databases success, applying config") + + executor.ApplyConfig(cfg, false) + }) } defer executor.Shutdown() @@ -145,39 +145,3 @@ func main() { } } } - -func updateGeoDatabases() { - log.Infoln("[GEO] Start updating GEO database") - updateGeoMux.Lock() - - if updatingGeo { - updateGeoMux.Unlock() - log.Infoln("[GEO] GEO database is updating, skip") - return - } - - updatingGeo = true - updateGeoMux.Unlock() - - go func() { - defer func() { - updatingGeo = false - }() - - log.Infoln("[GEO] Updating GEO database") - - if err := config.UpdateGeoDatabases(); err != nil { - log.Errorln("[GEO] update GEO database error: %s", err.Error()) - return - } - - cfg, err := executor.ParseWithPath(C.Path.Config()) - if err != nil { - log.Errorln("[GEO] update GEO database failed: %s", err.Error()) - return - } - - log.Infoln("[GEO] Update GEO database success, apply new config") - executor.ApplyConfig(cfg, false) - }() -} diff --git a/clash-meta-android/core/src/foss/golang/clash/rules/common/domain_regex.go b/clash-meta-android/core/src/foss/golang/clash/rules/common/domain_regex.go index 3d961542ad..d214a772c1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/rules/common/domain_regex.go +++ b/clash-meta-android/core/src/foss/golang/clash/rules/common/domain_regex.go @@ -1,14 +1,14 @@ package common import ( - "regexp" - C "github.com/metacubex/mihomo/constant" + + "github.com/dlclark/regexp2" ) type DomainRegex struct { *Base - regex *regexp.Regexp + regex *regexp2.Regexp adapter string } @@ -18,7 +18,8 @@ func (dr *DomainRegex) RuleType() C.RuleType { func (dr *DomainRegex) Match(metadata *C.Metadata) (bool, string) { domain := metadata.RuleHost() - return dr.regex.MatchString(domain), dr.adapter + match, _ := dr.regex.MatchString(domain) + return match, dr.adapter } func (dr *DomainRegex) Adapter() string { @@ -30,7 +31,7 @@ func (dr *DomainRegex) Payload() string { } func NewDomainRegex(regex string, adapter string) (*DomainRegex, error) { - r, err := regexp.Compile(regex) + r, err := regexp2.Compile(regex, regexp2.IgnoreCase) if err != nil { return nil, err } diff --git a/clash-meta-android/core/src/foss/golang/clash/rules/common/process.go b/clash-meta-android/core/src/foss/golang/clash/rules/common/process.go index ce6435941a..8932e94660 100644 --- a/clash-meta-android/core/src/foss/golang/clash/rules/common/process.go +++ b/clash-meta-android/core/src/foss/golang/clash/rules/common/process.go @@ -4,6 +4,8 @@ import ( "strings" C "github.com/metacubex/mihomo/constant" + + "github.com/dlclark/regexp2" ) type Process struct { @@ -11,21 +13,36 @@ type Process struct { adapter string process string nameOnly bool + regexp *regexp2.Regexp } func (ps *Process) RuleType() C.RuleType { if ps.nameOnly { - return C.Process + if ps.regexp != nil { + return C.ProcessNameRegex + } + return C.ProcessName } + if ps.regexp != nil { + return C.ProcessPathRegex + } return C.ProcessPath } func (ps *Process) Match(metadata *C.Metadata) (bool, string) { if ps.nameOnly { + if ps.regexp != nil { + match, _ := ps.regexp.MatchString(metadata.Process) + return match, ps.adapter + } return strings.EqualFold(metadata.Process, ps.process), ps.adapter } + if ps.regexp != nil { + match, _ := ps.regexp.MatchString(metadata.ProcessPath) + return match, ps.adapter + } return strings.EqualFold(metadata.ProcessPath, ps.process), ps.adapter } @@ -41,11 +58,20 @@ func (ps *Process) ShouldFindProcess() bool { return true } -func NewProcess(process string, adapter string, nameOnly bool) (*Process, error) { +func NewProcess(process string, adapter string, nameOnly bool, regex bool) (*Process, error) { + var r *regexp2.Regexp + var err error + if regex { + r, err = regexp2.Compile(process, regexp2.IgnoreCase) + if err != nil { + return nil, err + } + } return &Process{ Base: &Base{}, adapter: adapter, process: process, nameOnly: nameOnly, + regexp: r, }, nil } diff --git a/clash-meta-android/core/src/foss/golang/clash/rules/parser.go b/clash-meta-android/core/src/foss/golang/clash/rules/parser.go index 032a02e4b0..9b1f552007 100644 --- a/clash-meta-android/core/src/foss/golang/clash/rules/parser.go +++ b/clash-meta-android/core/src/foss/golang/clash/rules/parser.go @@ -50,9 +50,13 @@ func ParseRule(tp, payload, target string, params []string, subRules map[string] case "DSCP": parsed, parseErr = RC.NewDSCP(payload, target) case "PROCESS-NAME": - parsed, parseErr = RC.NewProcess(payload, target, true) + parsed, parseErr = RC.NewProcess(payload, target, true, false) case "PROCESS-PATH": - parsed, parseErr = RC.NewProcess(payload, target, false) + parsed, parseErr = RC.NewProcess(payload, target, false, false) + case "PROCESS-NAME-REGEX": + parsed, parseErr = RC.NewProcess(payload, target, true, true) + case "PROCESS-PATH-REGEX": + parsed, parseErr = RC.NewProcess(payload, target, false, true) case "NETWORK": parsed, parseErr = RC.NewNetworkType(payload, target) case "UID": diff --git a/clash-meta-android/core/src/foss/golang/clash/rules/provider/classical_strategy.go b/clash-meta-android/core/src/foss/golang/clash/rules/provider/classical_strategy.go index 6a2dccd53e..8353ebce40 100644 --- a/clash-meta-android/core/src/foss/golang/clash/rules/provider/classical_strategy.go +++ b/clash-meta-android/core/src/foss/golang/clash/rules/provider/classical_strategy.go @@ -77,7 +77,7 @@ func ruleParse(ruleRaw string) (string, string, []string) { } else if len(item) == 2 { return item[0], item[1], nil } else if len(item) > 2 { - if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" || item[0] == "DOMAIN-REGEX" { + if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" || item[0] == "DOMAIN-REGEX" || item[0] == "PROCESS-NAME-REGEX" || item[0] == "PROCESS-PATH-REGEX" { return item[0], strings.Join(item[1:len(item)], ","), nil } else { return item[0], item[1], item[2:] diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/simple-obfs/http.go b/clash-meta-android/core/src/foss/golang/clash/transport/simple-obfs/http.go index 681c1864f3..a38b1d6971 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/simple-obfs/http.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/simple-obfs/http.go @@ -65,7 +65,10 @@ func (ho *HTTPObfs) Write(b []byte) (int, error) { if ho.firstRequest { randBytes := make([]byte, 16) fastrand.Read(randBytes) - req, _ := http.NewRequest("GET", fmt.Sprintf("http://%s/", ho.host), bytes.NewBuffer(b[:])) + req, err := http.NewRequest("GET", fmt.Sprintf("http://%s/", ho.host), bytes.NewBuffer(b[:])) + if err != nil { + return 0, err + } req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", fastrand.Int()%54, fastrand.Int()%2)) req.Header.Set("Upgrade", "websocket") req.Header.Set("Connection", "Upgrade") @@ -75,7 +78,7 @@ func (ho *HTTPObfs) Write(b []byte) (int, error) { } req.Header.Set("Sec-WebSocket-Key", base64.URLEncoding.EncodeToString(randBytes)) req.ContentLength = int64(len(b)) - err := req.Write(ho.Conn) + err = req.Write(ho.Conn) ho.firstRequest = false return len(b), err } diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/sing-shadowtls/shadowtls.go b/clash-meta-android/core/src/foss/golang/clash/transport/sing-shadowtls/shadowtls.go index 982d847a51..2012e20a3a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/sing-shadowtls/shadowtls.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/sing-shadowtls/shadowtls.go @@ -9,9 +9,9 @@ import ( tlsC "github.com/metacubex/mihomo/component/tls" "github.com/metacubex/mihomo/log" + utls "github.com/metacubex/utls" "github.com/sagernet/sing-shadowtls" sing_common "github.com/sagernet/sing/common" - utls "github.com/sagernet/utls" ) const ( 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 09be112473..17f403c12d 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 @@ -129,6 +129,12 @@ func (t *Trojan) StreamWebsocketConn(ctx context.Context, conn net.Conn, wsOptio ServerName: t.option.ServerName, } + var err error + tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint) + if err != nil { + return nil, err + } + return vmess.StreamWebsocketConn(ctx, conn, &vmess.WebsocketConfig{ Host: wsOptions.Host, Port: wsOptions.Port, 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 485e2e6a60..a0e2be68dd 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 @@ -22,7 +22,7 @@ func SetCongestionController(quicConn quic.Connection, cc string, cwnd int) { quicConn.SetCongestionControl( congestion.NewCubicSender( congestion.DefaultClock{}, - congestion.GetInitialPacketSize(quicConn.RemoteAddr()), + congestion.GetInitialPacketSize(quicConn), false, ), ) @@ -30,7 +30,7 @@ func SetCongestionController(quicConn quic.Connection, cc string, cwnd int) { quicConn.SetCongestionControl( congestion.NewCubicSender( congestion.DefaultClock{}, - congestion.GetInitialPacketSize(quicConn.RemoteAddr()), + congestion.GetInitialPacketSize(quicConn), true, ), ) @@ -38,7 +38,7 @@ func SetCongestionController(quicConn quic.Connection, cc string, cwnd int) { quicConn.SetCongestionControl( congestion.NewBBRSender( congestion.DefaultClock{}, - congestion.GetInitialPacketSize(quicConn.RemoteAddr()), + congestion.GetInitialPacketSize(quicConn), c.ByteCount(cwnd)*congestion.InitialMaxDatagramSize, congestion.DefaultBBRMaxCongestionWindow*congestion.InitialMaxDatagramSize, ), @@ -49,7 +49,7 @@ func SetCongestionController(quicConn quic.Connection, cc string, cwnd int) { quicConn.SetCongestionControl( congestionv2.NewBbrSender( congestionv2.DefaultClock{}, - congestionv2.GetInitialPacketSize(quicConn.RemoteAddr()), + 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 8c18c616b7..6cea9355fb 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 @@ -5,34 +5,23 @@ package congestion import ( "fmt" "math" - "net" "time" + "github.com/metacubex/quic-go" "github.com/metacubex/quic-go/congestion" "github.com/zhangyunhao116/fastrand" ) const ( // InitialMaxDatagramSize is the default maximum packet size used in QUIC for congestion window computations in bytes. - InitialMaxDatagramSize = 1252 - InitialPacketSizeIPv4 = 1252 - InitialPacketSizeIPv6 = 1232 + InitialMaxDatagramSize = 1280 + InitialPacketSize = 1280 InitialCongestionWindow = 32 DefaultBBRMaxCongestionWindow = 10000 ) -func GetInitialPacketSize(addr net.Addr) congestion.ByteCount { - maxSize := congestion.ByteCount(1200) - // If this is not a UDP address, we don't know anything about the MTU. - // Use the minimum size of an Initial packet as the max packet size. - if udpAddr, ok := addr.(*net.UDPAddr); ok { - if udpAddr.IP.To4() != nil { - maxSize = InitialPacketSizeIPv4 - } else { - maxSize = InitialPacketSizeIPv6 - } - } - return congestion.ByteCount(maxSize) +func GetInitialPacketSize(quicConn quic.Connection) congestion.ByteCount { + return congestion.ByteCount(quicConn.Config().InitialPacketSize) } var ( 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 dd491a326a..a9bed43aa1 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 @@ -21,7 +21,7 @@ const ( cubeCongestionWindowScale = 410 cubeFactor congestion.ByteCount = 1 << cubeScale / cubeCongestionWindowScale / maxDatagramSize // TODO: when re-enabling cubic, make sure to use the actual packet size here - maxDatagramSize = congestion.ByteCount(InitialPacketSizeIPv4) + maxDatagramSize = congestion.ByteCount(InitialPacketSize) ) const defaultNumConnections = 1 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 084f85b12c..54705978cc 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 @@ -4,9 +4,9 @@ package congestion import ( "fmt" - "net" "time" + "github.com/metacubex/quic-go" "github.com/metacubex/quic-go/congestion" "github.com/zhangyunhao116/fastrand" @@ -30,7 +30,7 @@ const ( // Constants based on TCP defaults. // The minimum CWND to ensure delayed acks don't reduce bandwidth measurements. // Does not inflate the pacing rate. - defaultMinimumCongestionWindow = 4 * congestion.ByteCount(congestion.InitialPacketSizeIPv4) + defaultMinimumCongestionWindow = 4 * congestion.ByteCount(congestion.InitialPacketSize) // The gain used for the STARTUP, equal to 2/ln(2). defaultHighGain = 2.885 @@ -931,16 +931,6 @@ func bdpFromRttAndBandwidth(rtt time.Duration, bandwidth Bandwidth) congestion.B return congestion.ByteCount(rtt) * congestion.ByteCount(bandwidth) / congestion.ByteCount(BytesPerSecond) / congestion.ByteCount(time.Second) } -func GetInitialPacketSize(addr net.Addr) congestion.ByteCount { - // If this is not a UDP address, we don't know anything about the MTU. - // Use the minimum size of an Initial packet as the max packet size. - if udpAddr, ok := addr.(*net.UDPAddr); ok { - if udpAddr.IP.To4() != nil { - return congestion.InitialPacketSizeIPv4 - } else { - return congestion.InitialPacketSizeIPv6 - } - } else { - return congestion.MinInitialPacketSize - } +func GetInitialPacketSize(quicConn quic.Connection) congestion.ByteCount { + return congestion.ByteCount(quicConn.Config().InitialPacketSize) } diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/pacer.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/pacer.go index ecaf3d1154..174b3dbe3f 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/pacer.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/pacer.go @@ -21,8 +21,8 @@ type Pacer struct { func NewPacer(getBandwidth func() congestion.ByteCount) *Pacer { p := &Pacer{ - budgetAtLastSent: maxBurstPackets * congestion.InitialPacketSizeIPv4, - maxDatagramSize: congestion.InitialPacketSizeIPv4, + budgetAtLastSent: maxBurstPackets * congestion.InitialPacketSize, + maxDatagramSize: congestion.InitialPacketSize, getBandwidth: getBandwidth, } return p 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 5ad28134ed..69ccfba0c3 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 @@ -14,7 +14,7 @@ import ( "github.com/metacubex/mihomo/log" "github.com/gofrs/uuid/v5" - utls "github.com/sagernet/utls" + utls "github.com/metacubex/utls" ) var ( diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/vision.go b/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/vision.go index 09299b2305..3b9e9379e9 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/vision.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/vision.go @@ -14,8 +14,8 @@ import ( tlsC "github.com/metacubex/mihomo/component/tls" "github.com/gofrs/uuid/v5" + utls "github.com/metacubex/utls" "github.com/sagernet/sing/common" - utls "github.com/sagernet/utls" ) var ErrNotTLS13 = errors.New("XTLS Vision based on TLS 1.3 outer connection") 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 b023fee41e..4a1b93ecd8 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 @@ -66,7 +66,10 @@ func (hc *httpConn) Write(b []byte) (int, error) { } u := fmt.Sprintf("http://%s%s", net.JoinHostPort(host, "80"), path) - req, _ := http.NewRequest(utils.EmptyOr(hc.cfg.Method, http.MethodGet), u, bytes.NewBuffer(b)) + req, err := http.NewRequest(utils.EmptyOr(hc.cfg.Method, http.MethodGet), u, bytes.NewBuffer(b)) + if err != nil { + return 0, err + } for key, list := range hc.cfg.Headers { req.Header.Set(key, list[fastrand.Intn(len(list))]) } diff --git a/clash-meta-android/core/src/foss/golang/go.mod b/clash-meta-android/core/src/foss/golang/go.mod index aa605bbc3e..f5e3640c99 100644 --- a/clash-meta-android/core/src/foss/golang/go.mod +++ b/clash-meta-android/core/src/foss/golang/go.mod @@ -29,8 +29,8 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/gobwas/ws v1.3.2 // indirect - github.com/gofrs/uuid/v5 v5.1.0 // indirect + github.com/gobwas/ws v1.4.0 // indirect + github.com/gofrs/uuid/v5 v5.2.0 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect @@ -47,14 +47,15 @@ require ( github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec // indirect github.com/metacubex/mihomo v1.7.0 // indirect - github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6 // indirect - github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f // indirect + github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 // indirect + github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 // indirect github.com/metacubex/sing-shadowsocks v0.2.6 // indirect github.com/metacubex/sing-shadowsocks2 v0.2.0 // indirect - github.com/metacubex/sing-tun v0.2.6 // indirect + github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec // indirect github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f // indirect github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 // indirect github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 // indirect + github.com/metacubex/utls v1.6.6 // indirect github.com/miekg/dns v1.1.59 // indirect github.com/mroth/weightedrand/v2 v2.1.0 // indirect github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect @@ -72,10 +73,9 @@ require ( github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 // indirect github.com/sagernet/sing-shadowtls v0.1.4 // indirect github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect - github.com/sagernet/utls v1.5.4 // indirect github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e // indirect github.com/samber/lo v1.39.0 // indirect - github.com/shirou/gopsutil/v3 v3.24.3 // indirect + github.com/shirou/gopsutil/v3 v3.24.4 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c // indirect @@ -91,19 +91,19 @@ require ( gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.uber.org/mock v0.4.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/tools v0.21.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.2 // indirect + lukechampine.com/blake3 v1.3.0 // indirect ) replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240111014253-f1818b6a82b2 diff --git a/clash-meta-android/core/src/foss/golang/go.sum b/clash-meta-android/core/src/foss/golang/go.sum index 7e08513769..f6ddc7b7d0 100644 --- a/clash-meta-android/core/src/foss/golang/go.sum +++ b/clash-meta-android/core/src/foss/golang/go.sum @@ -54,10 +54,10 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= 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.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q= -github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/gofrs/uuid/v5 v5.1.0 h1:S5rqVKIigghZTCBKPCw0Y+bXkn26K3TB5mvQq2Ix8dk= -github.com/gofrs/uuid/v5 v5.1.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +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.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM= +github.com/gofrs/uuid/v5 v5.2.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/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -98,24 +98,26 @@ 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-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc= github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw= -github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6 h1:qqIZ8CjoxVJP38JU9ml1RkWJfaUd7QtmOk1vl7shuRY= -github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6/go.mod h1:uXHODgJFUfUnkkCMWLd5Er6L5QY/LFRZb9LD5jyyhsk= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 h1:hsQ0b2A509b6ubnLtLOcUgZ8vOb+d/667zVEJ1T2fao= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= github.com/metacubex/sing v0.0.0-20240111014253-f1818b6a82b2 h1:upEO8dt9WDBavhgcgkXB3hRcwVNbkTbnd+xyzy6ZQZo= github.com/metacubex/sing v0.0.0-20240111014253-f1818b6a82b2/go.mod h1:9pfuAH6mZfgnz/YjP6xu5sxx882rfyjpcrTdUpd6w3g= -github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f h1:Xyd8SHaPHS3iX3xXPnus9PsYhJIo/2e7sJ6vTKLKUm8= -github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f/go.mod h1:nfqibK+vkBtE6Ch8vYqrFTcaX4BC6TwKqNNl5rORll4= +github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew= +github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8= github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwVSgtE9R3QeFQ= github.com/metacubex/sing-shadowsocks v0.2.6/go.mod h1:zIkMeSnb8Mbf4hdqhw0pjzkn1d99YJ3JQm/VBg5WMTg= github.com/metacubex/sing-shadowsocks2 v0.2.0 h1:hqwT/AfI5d5UdPefIzR6onGHJfDXs5zgOM5QSgaM/9A= github.com/metacubex/sing-shadowsocks2 v0.2.0/go.mod h1:LCKF6j1P94zN8ZS+LXRK1gmYTVGB3squivBSXAFnOg8= -github.com/metacubex/sing-tun v0.2.6 h1:frc58BqnIClqcC9KcYBfVAn5bgO6WW1ANKvZW3/HYAQ= -github.com/metacubex/sing-tun v0.2.6/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= +github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec h1:K4Wq3GOdLZ/xcqwyzAt4kmYQrjokyKQ3u/Xh5Yft14U= +github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 h1:AGyIB55UfQm/0ZH0HtQO9u3l//yjtHUpjeRjjPGfGRI= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63/go.mod h1:uY+BYb0UEknLrqvbGcwi9i++KgrKxsurysgI6G1Pveo= github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 h1:as/aO/fM8nv4W4pOr9EETP6kV/Oaujk3fUNyQSJK61c= github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts= +github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8= +github.com/metacubex/utls v1.6.6/go.mod h1:+WLFUnXjcpdxXCnyX25nggw8C6YonZ8zOK2Zm/oRvdo= github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU= @@ -156,14 +158,12 @@ github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnV github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo= -github.com/sagernet/utls v1.5.4 h1:KmsEGbB2dKUtCNC+44NwAdNAqnqQ6GA4pTO0Yik56co= -github.com/sagernet/utls v1.5.4/go.mod h1:CTGxPWExIloRipK3XFpYv0OVyhO8kk3XCGW/ieyTh1s= github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e h1:iGH0RMv2FzELOFNFQtvsxH7NPmlo7X5JizEK51UCojo= github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e/go.mod h1:YbL4TKHRR6APYQv3U2RGfwLDpPYSyWz6oUlpISBEzBE= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= -github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= +github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= +github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -213,18 +213,18 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -244,22 +244,22 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -267,5 +267,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= -lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= diff --git a/clash-meta-android/core/src/main/golang/go.mod b/clash-meta-android/core/src/main/golang/go.mod index 8f72bf3fd7..4aaac4a47a 100644 --- a/clash-meta-android/core/src/main/golang/go.mod +++ b/clash-meta-android/core/src/main/golang/go.mod @@ -37,8 +37,8 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/gobwas/ws v1.3.2 // indirect - github.com/gofrs/uuid/v5 v5.1.0 // indirect + github.com/gobwas/ws v1.4.0 // indirect + github.com/gofrs/uuid/v5 v5.2.0 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect @@ -54,14 +54,15 @@ require ( github.com/mdlayher/socket v0.4.1 // indirect github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec // indirect - github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6 // indirect - github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f // indirect + github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 // indirect + github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 // indirect github.com/metacubex/sing-shadowsocks v0.2.6 // indirect github.com/metacubex/sing-shadowsocks2 v0.2.0 // indirect - github.com/metacubex/sing-tun v0.2.6 // indirect + github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec // indirect github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f // indirect github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 // indirect github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 // indirect + github.com/metacubex/utls v1.6.6 // indirect github.com/mroth/weightedrand/v2 v2.1.0 // indirect github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect @@ -77,10 +78,9 @@ require ( github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 // indirect github.com/sagernet/sing-shadowtls v0.1.4 // indirect github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect - github.com/sagernet/utls v1.5.4 // indirect github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e // indirect github.com/samber/lo v1.39.0 // indirect - github.com/shirou/gopsutil/v3 v3.24.3 // indirect + github.com/shirou/gopsutil/v3 v3.24.4 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c // indirect @@ -96,15 +96,15 @@ require ( gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.uber.org/mock v0.4.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/tools v0.21.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.2 // indirect + lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/clash-meta-android/core/src/main/golang/go.sum b/clash-meta-android/core/src/main/golang/go.sum index 7e08513769..f6ddc7b7d0 100644 --- a/clash-meta-android/core/src/main/golang/go.sum +++ b/clash-meta-android/core/src/main/golang/go.sum @@ -54,10 +54,10 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= 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.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q= -github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/gofrs/uuid/v5 v5.1.0 h1:S5rqVKIigghZTCBKPCw0Y+bXkn26K3TB5mvQq2Ix8dk= -github.com/gofrs/uuid/v5 v5.1.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +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.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM= +github.com/gofrs/uuid/v5 v5.2.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/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -98,24 +98,26 @@ 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-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc= github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw= -github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6 h1:qqIZ8CjoxVJP38JU9ml1RkWJfaUd7QtmOk1vl7shuRY= -github.com/metacubex/quic-go v0.43.1-0.20240428051621-a109abfb4cf6/go.mod h1:uXHODgJFUfUnkkCMWLd5Er6L5QY/LFRZb9LD5jyyhsk= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 h1:hsQ0b2A509b6ubnLtLOcUgZ8vOb+d/667zVEJ1T2fao= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= github.com/metacubex/sing v0.0.0-20240111014253-f1818b6a82b2 h1:upEO8dt9WDBavhgcgkXB3hRcwVNbkTbnd+xyzy6ZQZo= github.com/metacubex/sing v0.0.0-20240111014253-f1818b6a82b2/go.mod h1:9pfuAH6mZfgnz/YjP6xu5sxx882rfyjpcrTdUpd6w3g= -github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f h1:Xyd8SHaPHS3iX3xXPnus9PsYhJIo/2e7sJ6vTKLKUm8= -github.com/metacubex/sing-quic v0.0.0-20240501013754-2a2b0f262f9f/go.mod h1:nfqibK+vkBtE6Ch8vYqrFTcaX4BC6TwKqNNl5rORll4= +github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew= +github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8= github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwVSgtE9R3QeFQ= github.com/metacubex/sing-shadowsocks v0.2.6/go.mod h1:zIkMeSnb8Mbf4hdqhw0pjzkn1d99YJ3JQm/VBg5WMTg= github.com/metacubex/sing-shadowsocks2 v0.2.0 h1:hqwT/AfI5d5UdPefIzR6onGHJfDXs5zgOM5QSgaM/9A= github.com/metacubex/sing-shadowsocks2 v0.2.0/go.mod h1:LCKF6j1P94zN8ZS+LXRK1gmYTVGB3squivBSXAFnOg8= -github.com/metacubex/sing-tun v0.2.6 h1:frc58BqnIClqcC9KcYBfVAn5bgO6WW1ANKvZW3/HYAQ= -github.com/metacubex/sing-tun v0.2.6/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= +github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec h1:K4Wq3GOdLZ/xcqwyzAt4kmYQrjokyKQ3u/Xh5Yft14U= +github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 h1:AGyIB55UfQm/0ZH0HtQO9u3l//yjtHUpjeRjjPGfGRI= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63/go.mod h1:uY+BYb0UEknLrqvbGcwi9i++KgrKxsurysgI6G1Pveo= github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 h1:as/aO/fM8nv4W4pOr9EETP6kV/Oaujk3fUNyQSJK61c= github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts= +github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8= +github.com/metacubex/utls v1.6.6/go.mod h1:+WLFUnXjcpdxXCnyX25nggw8C6YonZ8zOK2Zm/oRvdo= github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU= @@ -156,14 +158,12 @@ github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnV github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo= -github.com/sagernet/utls v1.5.4 h1:KmsEGbB2dKUtCNC+44NwAdNAqnqQ6GA4pTO0Yik56co= -github.com/sagernet/utls v1.5.4/go.mod h1:CTGxPWExIloRipK3XFpYv0OVyhO8kk3XCGW/ieyTh1s= github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e h1:iGH0RMv2FzELOFNFQtvsxH7NPmlo7X5JizEK51UCojo= github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e/go.mod h1:YbL4TKHRR6APYQv3U2RGfwLDpPYSyWz6oUlpISBEzBE= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= -github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= +github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= +github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -213,18 +213,18 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -244,22 +244,22 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -267,5 +267,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w= -lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= diff --git a/clash-meta/common/convert/converter.go b/clash-meta/common/convert/converter.go index 222dd9fa82..19886d25ee 100644 --- a/clash-meta/common/convert/converter.go +++ b/clash-meta/common/convert/converter.go @@ -333,7 +333,7 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { case "ws", "httpupgrade": headers := make(map[string]any) wsOpts := make(map[string]any) - wsOpts["path"] = []string{"/"} + wsOpts["path"] = "/" if host, ok := values["host"]; ok && host != "" { headers["Host"] = host.(string) } diff --git a/clash-meta/go.mod b/clash-meta/go.mod index 601929c189..08e5b5aa06 100644 --- a/clash-meta/go.mod +++ b/clash-meta/go.mod @@ -19,11 +19,11 @@ require ( github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/mdlayher/netlink v1.7.2 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 - github.com/metacubex/quic-go v0.44.1-0.20240520163451-20b689a59136 + github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 github.com/metacubex/sing-shadowsocks v0.2.6 github.com/metacubex/sing-shadowsocks2 v0.2.0 - github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec + github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414 github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 diff --git a/clash-meta/go.sum b/clash-meta/go.sum index 091f6cf126..b9f1af1449 100644 --- a/clash-meta/go.sum +++ b/clash-meta/go.sum @@ -104,8 +104,8 @@ 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-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc= github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw= -github.com/metacubex/quic-go v0.44.1-0.20240520163451-20b689a59136 h1:Z9XGYDs6QuSqipNcxbTx+baN/bBBAIpRxVhLpoMF42U= -github.com/metacubex/quic-go v0.44.1-0.20240520163451-20b689a59136/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 h1:hsQ0b2A509b6ubnLtLOcUgZ8vOb+d/667zVEJ1T2fao= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1 h1:7hDHLTmjgtRoAp59STwPQpe5Pinwi4cWex+FB3Ohvco= github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew= @@ -114,8 +114,8 @@ github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwV github.com/metacubex/sing-shadowsocks v0.2.6/go.mod h1:zIkMeSnb8Mbf4hdqhw0pjzkn1d99YJ3JQm/VBg5WMTg= github.com/metacubex/sing-shadowsocks2 v0.2.0 h1:hqwT/AfI5d5UdPefIzR6onGHJfDXs5zgOM5QSgaM/9A= github.com/metacubex/sing-shadowsocks2 v0.2.0/go.mod h1:LCKF6j1P94zN8ZS+LXRK1gmYTVGB3squivBSXAFnOg8= -github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec h1:K4Wq3GOdLZ/xcqwyzAt4kmYQrjokyKQ3u/Xh5Yft14U= -github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= +github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414 h1:IPxTZgQV6fVUBS8tozLMSFPHV3imYc/NbuGfp0bLQq0= +github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 h1:AGyIB55UfQm/0ZH0HtQO9u3l//yjtHUpjeRjjPGfGRI= diff --git a/clash-meta/listener/sing_tun/server.go b/clash-meta/listener/sing_tun/server.go index 2dc6524ee3..09bf308c73 100644 --- a/clash-meta/listener/sing_tun/server.go +++ b/clash-meta/listener/sing_tun/server.go @@ -59,15 +59,23 @@ func CalculateInterfaceName(name string) (tunName string) { if err != nil { return } - var tunIndex int + tunIndex := 0 + indexSet := make(map[int]struct{}) for _, netInterface := range interfaces { if strings.HasPrefix(netInterface.Name, tunName) { index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16) if parseErr == nil { - tunIndex = int(index) + 1 + indexSet[int(index)] = struct{}{} } } } + for index := range indexSet { + if index == tunIndex { + tunIndex += 1 + } else { // indexSet already sorted and distinct, so this tunIndex nobody used + break + } + } tunName = F.ToString(tunName, tunIndex) return } diff --git a/clash-meta/listener/tproxy/packet.go b/clash-meta/listener/tproxy/packet.go index e485266515..b038d954f8 100644 --- a/clash-meta/listener/tproxy/packet.go +++ b/clash-meta/listener/tproxy/packet.go @@ -105,9 +105,9 @@ func listenLocalConn(rAddr, lAddr net.Addr, tunnel C.Tunnel) (*net.UDPConn, erro buf := pool.Get(pool.UDPBufferSize) br, err := lc.Read(buf) if err != nil { - pool.Put(buf) if errors.Is(err, net.ErrClosed) { log.Debugln("TProxy local conn listener exit.. rAddr=%s lAddr=%s", rAddr.String(), lAddr.String()) + pool.Put(buf) return } } diff --git a/clash-nyanpasu/backend/tauri/src/core/commands/mod.rs b/clash-nyanpasu/backend/tauri/src/core/commands/mod.rs index c392bee51c..6ea67d8471 100644 --- a/clash-nyanpasu/backend/tauri/src/core/commands/mod.rs +++ b/clash-nyanpasu/backend/tauri/src/core/commands/mod.rs @@ -148,7 +148,7 @@ mod handler { } #[cfg(not(target_os = "windows"))] - pub fn migrate_home_dir_handler(target_path: &str) -> anyhow::Result<()> { + pub fn migrate_home_dir_handler(_target_path: &str) -> anyhow::Result<()> { Ok(()) } } diff --git a/clash-nyanpasu/backend/tauri/src/core/hotkey.rs b/clash-nyanpasu/backend/tauri/src/core/hotkey.rs index 62776cc5c6..8b4f308e1c 100644 --- a/clash-nyanpasu/backend/tauri/src/core/hotkey.rs +++ b/clash-nyanpasu/backend/tauri/src/core/hotkey.rs @@ -54,7 +54,7 @@ impl Hotkey { } } } - *self.current.lock() = hotkeys.clone(); + self.current.lock().clone_from(hotkeys); } Ok(()) diff --git a/clash-nyanpasu/backend/tauri/src/core/tray/icon.rs b/clash-nyanpasu/backend/tauri/src/core/tray/icon.rs index 20e96b6cdf..1175935d3b 100644 --- a/clash-nyanpasu/backend/tauri/src/core/tray/icon.rs +++ b/clash-nyanpasu/backend/tauri/src/core/tray/icon.rs @@ -86,6 +86,7 @@ pub fn on_scale_factor_changed(scale_factor: f64) { resize_images(&RESIZED_ICON_CACHE, scale_factor); } +#[allow(dead_code)] pub fn get_icon(mode: &TrayIcon) -> Vec { RESIZED_ICON_CACHE .clone() diff --git a/clash-nyanpasu/backend/tauri/src/core/tray/mod.rs b/clash-nyanpasu/backend/tauri/src/core/tray/mod.rs index 13ea8415bc..eab758290e 100644 --- a/clash-nyanpasu/backend/tauri/src/core/tray/mod.rs +++ b/clash-nyanpasu/backend/tauri/src/core/tray/mod.rs @@ -10,7 +10,7 @@ use tracing_attributes::instrument; mod icon; pub mod proxies; pub use self::icon::on_scale_factor_changed; -use self::{icon::TrayIcon, proxies::SystemTrayMenuProxiesExt}; +use self::proxies::SystemTrayMenuProxiesExt; pub struct Tray {} @@ -95,6 +95,8 @@ impl Tray { #[cfg(target_os = "windows")] { + use icon::TrayIcon; + let mode = if *tun_mode { TrayIcon::Tun } else if *system_proxy { diff --git a/clash-nyanpasu/backend/tauri/src/utils/dirs.rs b/clash-nyanpasu/backend/tauri/src/utils/dirs.rs index fe3e9313d3..63a1dc3385 100644 --- a/clash-nyanpasu/backend/tauri/src/utils/dirs.rs +++ b/clash-nyanpasu/backend/tauri/src/utils/dirs.rs @@ -1,6 +1,6 @@ use crate::core::handle; use anyhow::Result; -use std::{path::PathBuf, sync::OnceLock}; +use std::path::PathBuf; use tauri::{ api::path::{home_dir, resource_dir}, Env, @@ -23,7 +23,7 @@ static STORAGE_DB: &str = "storage.db"; /// portable flag #[allow(unused)] #[cfg(target_os = "windows")] -static PORTABLE_FLAG: OnceLock = OnceLock::new(); +static PORTABLE_FLAG: std::sync::OnceLock = std::sync::OnceLock::new(); pub static APP_VERSION: &str = env!("NYANPASU_VERSION"); diff --git a/clash-nyanpasu/backend/tauri/src/utils/init/mod.rs b/clash-nyanpasu/backend/tauri/src/utils/init/mod.rs index 3ccb36a50c..a222c6c389 100644 --- a/clash-nyanpasu/backend/tauri/src/utils/init/mod.rs +++ b/clash-nyanpasu/backend/tauri/src/utils/init/mod.rs @@ -4,6 +4,7 @@ use crate::{ }; use anyhow::{Context, Result}; use fs_extra::dir::CopyOptions; +#[cfg(windows)] use runas::Command as RunasCommand; use rust_i18n::t; use std::{fs, path::PathBuf}; diff --git a/clash-nyanpasu/backend/tauri/src/utils/resolve.rs b/clash-nyanpasu/backend/tauri/src/utils/resolve.rs index 559e5684ed..693918cadb 100644 --- a/clash-nyanpasu/backend/tauri/src/utils/resolve.rs +++ b/clash-nyanpasu/backend/tauri/src/utils/resolve.rs @@ -15,7 +15,7 @@ use anyhow::Result; use semver::Version; use serde_yaml::Mapping; use std::net::TcpListener; -use tauri::{api::process::Command, App, AppHandle, Manager, PhysicalPosition, PhysicalSize}; +use tauri::{api::process::Command, App, AppHandle, Manager}; pub fn find_unused_port() -> Result { match TcpListener::bind("127.0.0.1:0") { @@ -150,6 +150,7 @@ pub fn create_window(app_handle: &AppHandle) { #[cfg(target_os = "windows")] { + use tauri::{PhysicalPosition, PhysicalSize}; use window_shadows::set_shadow; match builder diff --git a/clash-nyanpasu/frontend/interface/ipc/useNyanpasu.ts b/clash-nyanpasu/frontend/interface/ipc/useNyanpasu.ts index 12f169cf0c..da77b7365f 100644 --- a/clash-nyanpasu/frontend/interface/ipc/useNyanpasu.ts +++ b/clash-nyanpasu/frontend/interface/ipc/useNyanpasu.ts @@ -50,7 +50,9 @@ export const useNyanpasu = (options?: { }, 100); }; - const getLatestCore = useSWR("getLatestCore", fetchLatestCore); + const getLatestCore = useSWR("getLatestCore", fetchLatestCore, { + revalidateOnMount: false, + }); const updateCore = async (core: Required["clash_core"]) => { await service.updateCore(core); @@ -104,31 +106,6 @@ export const useNyanpasu = (options?: { return modes; }, [data?.clash_core, getConfigs.data?.mode]); - const getProfiles = useSWR("getProfiles", tauri.getProfiles); - - const createProfile = async ( - item: Partial, - data?: string, - ) => { - await tauri.createProfile(item, data); - - await getProfiles.mutate(); - }; - - const getProfileFile = async (id?: string) => { - if (id) { - const result = await tauri.readProfileFile(id); - - if (result) { - return result; - } else { - return ""; - } - } else { - return ""; - } - }; - return { nyanpasuConfig: data, isLoading: !data && !error, @@ -145,9 +122,5 @@ export const useNyanpasu = (options?: { setServiceStatus, getCurrentMode, setCurrentMode, - createProfile, - getProfiles, - getProfileFile, - setProfileFile: tauri.saveProfileFile, }; }; diff --git a/clash-nyanpasu/frontend/nyanpasu/src/assets/styles/index.scss b/clash-nyanpasu/frontend/nyanpasu/src/assets/styles/index.scss index 2aff70f599..322ad9133c 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/assets/styles/index.scss +++ b/clash-nyanpasu/frontend/nyanpasu/src/assets/styles/index.scss @@ -47,6 +47,10 @@ body { border-radius: 6px; } +*::-webkit-scrollbar-track { + margin-block: calc(var(--border-radius) + 3px); +} + @media (prefers-color-scheme: dark) { :root { background-color: rgb(18 18 18 / 100%); diff --git a/clash-nyanpasu/frontend/nyanpasu/src/router.ts b/clash-nyanpasu/frontend/nyanpasu/src/router.ts index 56f4dff4a6..d5e7461ebb 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/router.ts +++ b/clash-nyanpasu/frontend/nyanpasu/src/router.ts @@ -1,7 +1,7 @@ // Generouted, changes to this file will be overriden /* eslint-disable */ -import { components, hooks, utils } from "@generouted/react-router/client"; +import { components, hooks, utils } from '@generouted/react-router/client' export type Path = | `/connections` @@ -10,16 +10,14 @@ export type Path = | `/providers` | `/proxies` | `/rules` - | `/settings`; + | `/settings` -export type Params = {}; +export type Params = { + +} -export type ModalPath = never; +export type ModalPath = never -export const { Link, Navigate } = components(); -export const { useModals, useNavigate, useParams } = hooks< - Path, - Params, - ModalPath ->(); -export const { redirect } = utils(); +export const { Link, Navigate } = components() +export const { useModals, useNavigate, useParams } = hooks() +export const { redirect } = utils() diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index d599842e0d..1053ae00aa 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.18.5", - "mihomo_alpha": "alpha-c504985", + "mihomo_alpha": "alpha-de3d214", "clash_rs": "v0.1.17", "clash_premium": "2023-09-05-gdcc8d87" }, @@ -36,5 +36,5 @@ "darwin-x64": "clash-darwin-amd64-n{}.gz" } }, - "updated_at": "2024-05-19T22:20:18.727Z" + "updated_at": "2024-05-20T22:19:34.353Z" } diff --git a/clash-nyanpasu/package.json b/clash-nyanpasu/package.json index c5274172a7..cab518f947 100644 --- a/clash-nyanpasu/package.json +++ b/clash-nyanpasu/package.json @@ -108,7 +108,7 @@ "tsx": "4.10.5", "typescript": "5.4.5" }, - "packageManager": "pnpm@9.1.1", + "packageManager": "pnpm@9.1.2+sha512.127dc83b9ea10c32be65d22a8efb4a65fb952e8fefbdfded39bdc3c97efc32d31b48b00420df2c1187ace28c921c902f0cb5a134a4d032b8b5295cbfa2c681e2", "engines": { "node": "21.7.3" }, diff --git a/clash-verge-rev/src/components/profile/editor-viewer.tsx b/clash-verge-rev/src/components/profile/editor-viewer.tsx index 0282c109e7..a41f7fcb01 100644 --- a/clash-verge-rev/src/components/profile/editor-viewer.tsx +++ b/clash-verge-rev/src/components/profile/editor-viewer.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from "react"; +import { ReactNode, useEffect, useRef } from "react"; import { useLockFn } from "ahooks"; import { useRecoilValue } from "recoil"; import { useTranslation } from "react-i18next"; @@ -24,9 +24,11 @@ import mergeSchema from "meta-json-schema/schemas/clash-verge-merge-json-schema. import pac from "types-pac/pac.d.ts?raw"; interface Props { + title?: string | ReactNode; mode: "profile" | "text"; property: string; open: boolean; + readOnly?: boolean; language: "yaml" | "javascript" | "css"; schema?: "clash" | "merge"; onClose: () => void; @@ -56,7 +58,17 @@ configureMonacoYaml(monaco, { monaco.languages.typescript.javascriptDefaults.addExtraLib(pac, "pac.d.ts"); export const EditorViewer = (props: Props) => { - const { mode, property, open, language, schema, onClose, onChange } = props; + const { + title, + mode, + property, + open, + readOnly, + language, + schema, + onClose, + onChange, + } = props; const { t } = useTranslation(); const editorRef = useRef(); const instanceRef = useRef(null); @@ -86,10 +98,13 @@ export const EditorViewer = (props: Props) => { instanceRef.current = editor.create(editorRef.current, { model: model, language: language, - tabSize: ["yaml", "javascript", "css"].includes(language) ? 2 : 4, // 根据语言类型设置缩进 + tabSize: ["yaml", "javascript", "css"].includes(language) ? 2 : 4, // 根据语言类型设置缩进大小 theme: themeMode === "light" ? "vs" : "vs-dark", minimap: { enabled: dom.clientWidth >= 1000 }, // 超过一定宽度显示minimap滚动条 - mouseWheelZoom: true, // Ctrl+滚轮调节缩放 + mouseWheelZoom: true, // 按住Ctrl滚轮调节缩放比例 + readOnly: readOnly, // 只读模式 + readOnlyMessage: { value: t("ReadOnlyMessage") }, // 只读模式尝试编辑时的提示信息 + renderValidationDecorations: "on", // 只读模式下显示校验信息 quickSuggestions: { strings: true, // 字符串类型的建议 comments: true, // 注释类型的建议 @@ -129,11 +144,9 @@ export const EditorViewer = (props: Props) => { return ( - {t("Edit File")} + {title ?? t("Edit File")} - +
diff --git a/clash-verge-rev/src/components/setting/mods/config-viewer.tsx b/clash-verge-rev/src/components/setting/mods/config-viewer.tsx index 8d092d061d..3f04356d4e 100644 --- a/clash-verge-rev/src/components/setting/mods/config-viewer.tsx +++ b/clash-verge-rev/src/components/setting/mods/config-viewer.tsx @@ -1,93 +1,40 @@ -import { - forwardRef, - useEffect, - useImperativeHandle, - useRef, - useState, -} from "react"; +import { forwardRef, useImperativeHandle, useState } from "react"; import { useTranslation } from "react-i18next"; -import { useRecoilValue } from "recoil"; -import { - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Chip, -} from "@mui/material"; -import { atomThemeMode } from "@/services/states"; +import { Box, Chip } from "@mui/material"; import { getRuntimeYaml } from "@/services/cmds"; import { DialogRef } from "@/components/base"; -import { editor } from "monaco-editor/esm/vs/editor/editor.api"; +import { EditorViewer } from "@/components/profile/editor-viewer"; -import "monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution.js"; -import "monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution.js"; -import "monaco-editor/esm/vs/editor/contrib/folding/browser/folding.js"; - -export const ConfigViewer = forwardRef((props, ref) => { +export const ConfigViewer = forwardRef((_, ref) => { const { t } = useTranslation(); const [open, setOpen] = useState(false); - - const editorRef = useRef(); - const instanceRef = useRef(null); - const themeMode = useRecoilValue(atomThemeMode); - - useEffect(() => { - return () => { - if (instanceRef.current) { - instanceRef.current.dispose(); - instanceRef.current = null; - } - }; - }, []); + const [runtimeConfig, setRuntimeConfig] = useState(""); useImperativeHandle(ref, () => ({ open: () => { - setOpen(true); - getRuntimeYaml().then((data) => { - const dom = editorRef.current; - - if (!dom) return; - if (instanceRef.current) instanceRef.current.dispose(); - - instanceRef.current = editor.create(editorRef.current, { - value: data ?? "# Error\n", - language: "yaml", - tabSize: 2, - theme: themeMode === "light" ? "vs" : "vs-dark", - minimap: { enabled: dom.clientWidth >= 1000 }, // 超过一定宽度显示minimap滚动条 - mouseWheelZoom: true, // Ctrl+滚轮调节缩放 - readOnly: true, // 只读 - readOnlyMessage: { value: t("ReadOnlyMessage") }, - padding: { - top: 33, // 顶部padding防止遮挡snippets - }, - fontFamily: - "Fira Code, Roboto Mono, Source Code Pro, Menlo, Monaco, Consolas, Courier New, monospace", - }); + setRuntimeConfig(data ?? "# Error getting runtime yaml\n"); + setOpen(true); }); }, close: () => setOpen(false), })); return ( - setOpen(false)} maxWidth="xl" fullWidth> - - {t("Runtime Config")} - - - -
- - - - - -
+ + {t("Runtime Config")} + + + } + mode="text" + property={runtimeConfig} + open={open} + readOnly + language="yaml" + schema="clash" + onClose={() => setOpen(false)} + /> ); }); diff --git a/clash-verge-rev/src/components/setting/mods/theme-viewer.tsx b/clash-verge-rev/src/components/setting/mods/theme-viewer.tsx index 7aa8424a29..5828e1ea2a 100644 --- a/clash-verge-rev/src/components/setting/mods/theme-viewer.tsx +++ b/clash-verge-rev/src/components/setting/mods/theme-viewer.tsx @@ -124,6 +124,7 @@ export const ThemeViewer = forwardRef((props, ref) => { {t("Edit")} CSS ; + hw_algo = "toggle"; + hw_margin_ms = <3000>; + always-running; + }; sound { compatible = "simple-audio-card"; @@ -38,6 +50,12 @@ }; &pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "rgmii2", "jtag"; + ralink,function = "gpio"; + }; + }; i2s_pins: i2s { i2s { groups = "uart3"; @@ -72,9 +90,10 @@ status = "okay"; flash@0 { - compatible = "mx25l6405d","jedec,spi-nor"; + compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <10000000>; + spi-max-frequency = <45000000>; + broken-flash-reset; partitions { compatible = "fixed-partitions"; @@ -102,7 +121,7 @@ partition@50000 { compatible = "denx,uimage"; label = "firmware"; - reg = <0x50000 0x7b0000>; + reg = <0x50000 0x1fb0000>; }; }; }; diff --git a/lede/target/linux/ramips/image/mt7621.mk b/lede/target/linux/ramips/image/mt7621.mk index be5676a44d..3b3a594799 100644 --- a/lede/target/linux/ramips/image/mt7621.mk +++ b/lede/target/linux/ramips/image/mt7621.mk @@ -1102,10 +1102,11 @@ TARGET_DEVICES += linksys_re6500 define Device/mediatek_ap-mt7621a-v60 $(Device/dsa-migration) - IMAGE_SIZE := 7872k + $(Device/uimage-lzma-loader) + IMAGE_SIZE := 32448k DEVICE_VENDOR := Mediatek DEVICE_MODEL := AP-MT7621A-V60 EVB - DEVICE_PACKAGES := kmod-usb3 kmod-sdhci-mt7620 kmod-sound-mt7620 -wpad-openssl + DEVICE_PACKAGES := kmod-usb3 kmod-i2c-gpio kmod-rtc-pcf8563 kmod-sdhci-mt7620 kmod-sound-mt7620 kmod-mt76x2 endef TARGET_DEVICES += mediatek_ap-mt7621a-v60 diff --git a/mieru/docs/operation.md b/mieru/docs/operation.md index aa58c9a37d..0e88bbac6e 100644 --- a/mieru/docs/operation.md +++ b/mieru/docs/operation.md @@ -80,18 +80,18 @@ To determine if the connectivity is OK, you can look at the client metrics. To g ```json { "cipher - client": { - "DirectDecrypt": 25683, + "DirectDecrypt": 64540, "FailedDirectDecrypt": 0 }, "connections": { - "ActiveOpens": 2, + "ActiveOpens": 130, "CurrEstablished": 2, - "MaxConn": 2, + "MaxConn": 35, "PassiveOpens": 0 }, "HTTP proxy": { - "ConnErrors": 0, - "Requests": 2, + "ConnErrors": 2, + "Requests": 130, "SchemeErrors": 0 }, "replay": { @@ -101,27 +101,27 @@ To determine if the connectivity is OK, you can look at the client metrics. To g "socks5": { "ConnectionRefusedErrors": 0, "DNSResolveErrors": 0, - "HandshakeErrors": 0, + "HandshakeErrors": 1, "HostUnreachableErrors": 0, "NetworkUnreachableErrors": 0, "UDPAssociateErrors": 0, "UnsupportedCommandErrors": 0 }, "socks5 UDP associate": { - "InBytes": 0, - "InPkts": 0, - "OutBytes": 0, - "OutPkts": 0 + "DownloadBytes": 0, + "DownloadPackets": 0, + "UploadBytes": 0, + "UploadPackets": 0 }, "traffic": { - "InBytes": 14680428, - "OutBytes": 1853242, - "OutPaddingBytes": 271334 + "DownloadBytes": 257341785, + "OutputPaddingBytes": 511223, + "UploadBytes": 1254325 }, "underlay": { - "ActiveOpens": 2, - "CurrEstablished": 2, - "MaxConn": 2, + "ActiveOpens": 16, + "CurrEstablished": 7, + "MaxConn": 11, "PassiveOpens": 0, "UnderlayMalformedUDP": 0, "UnsolicitedUDP": 0 diff --git a/mieru/docs/operation.zh_CN.md b/mieru/docs/operation.zh_CN.md index 00b3114474..34323a9df5 100644 --- a/mieru/docs/operation.zh_CN.md +++ b/mieru/docs/operation.zh_CN.md @@ -80,18 +80,18 @@ mieru start ```json { "cipher - client": { - "DirectDecrypt": 25683, + "DirectDecrypt": 64540, "FailedDirectDecrypt": 0 }, "connections": { - "ActiveOpens": 2, + "ActiveOpens": 130, "CurrEstablished": 2, - "MaxConn": 2, + "MaxConn": 35, "PassiveOpens": 0 }, "HTTP proxy": { - "ConnErrors": 0, - "Requests": 2, + "ConnErrors": 2, + "Requests": 130, "SchemeErrors": 0 }, "replay": { @@ -101,27 +101,27 @@ mieru start "socks5": { "ConnectionRefusedErrors": 0, "DNSResolveErrors": 0, - "HandshakeErrors": 0, + "HandshakeErrors": 1, "HostUnreachableErrors": 0, "NetworkUnreachableErrors": 0, "UDPAssociateErrors": 0, "UnsupportedCommandErrors": 0 }, "socks5 UDP associate": { - "InBytes": 0, - "InPkts": 0, - "OutBytes": 0, - "OutPkts": 0 + "DownloadBytes": 0, + "DownloadPackets": 0, + "UploadBytes": 0, + "UploadPackets": 0 }, "traffic": { - "InBytes": 14680428, - "OutBytes": 1853242, - "OutPaddingBytes": 271334 + "DownloadBytes": 257341785, + "OutputPaddingBytes": 511223, + "UploadBytes": 1254325 }, "underlay": { - "ActiveOpens": 2, - "CurrEstablished": 2, - "MaxConn": 2, + "ActiveOpens": 16, + "CurrEstablished": 7, + "MaxConn": 11, "PassiveOpens": 0, "UnderlayMalformedUDP": 0, "UnsolicitedUDP": 0 diff --git a/mihomo/common/convert/converter.go b/mihomo/common/convert/converter.go index 222dd9fa82..19886d25ee 100644 --- a/mihomo/common/convert/converter.go +++ b/mihomo/common/convert/converter.go @@ -333,7 +333,7 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { case "ws", "httpupgrade": headers := make(map[string]any) wsOpts := make(map[string]any) - wsOpts["path"] = []string{"/"} + wsOpts["path"] = "/" if host, ok := values["host"]; ok && host != "" { headers["Host"] = host.(string) } diff --git a/mihomo/go.mod b/mihomo/go.mod index 601929c189..08e5b5aa06 100644 --- a/mihomo/go.mod +++ b/mihomo/go.mod @@ -19,11 +19,11 @@ require ( github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/mdlayher/netlink v1.7.2 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 - github.com/metacubex/quic-go v0.44.1-0.20240520163451-20b689a59136 + github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 github.com/metacubex/sing-shadowsocks v0.2.6 github.com/metacubex/sing-shadowsocks2 v0.2.0 - github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec + github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414 github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66 diff --git a/mihomo/go.sum b/mihomo/go.sum index 091f6cf126..b9f1af1449 100644 --- a/mihomo/go.sum +++ b/mihomo/go.sum @@ -104,8 +104,8 @@ 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-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc= github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw= -github.com/metacubex/quic-go v0.44.1-0.20240520163451-20b689a59136 h1:Z9XGYDs6QuSqipNcxbTx+baN/bBBAIpRxVhLpoMF42U= -github.com/metacubex/quic-go v0.44.1-0.20240520163451-20b689a59136/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 h1:hsQ0b2A509b6ubnLtLOcUgZ8vOb+d/667zVEJ1T2fao= +github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1 h1:7hDHLTmjgtRoAp59STwPQpe5Pinwi4cWex+FB3Ohvco= github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew= @@ -114,8 +114,8 @@ github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwV github.com/metacubex/sing-shadowsocks v0.2.6/go.mod h1:zIkMeSnb8Mbf4hdqhw0pjzkn1d99YJ3JQm/VBg5WMTg= github.com/metacubex/sing-shadowsocks2 v0.2.0 h1:hqwT/AfI5d5UdPefIzR6onGHJfDXs5zgOM5QSgaM/9A= github.com/metacubex/sing-shadowsocks2 v0.2.0/go.mod h1:LCKF6j1P94zN8ZS+LXRK1gmYTVGB3squivBSXAFnOg8= -github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec h1:K4Wq3GOdLZ/xcqwyzAt4kmYQrjokyKQ3u/Xh5Yft14U= -github.com/metacubex/sing-tun v0.2.7-0.20240512075008-89e7c6208eec/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= +github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414 h1:IPxTZgQV6fVUBS8tozLMSFPHV3imYc/NbuGfp0bLQq0= +github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ= github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 h1:AGyIB55UfQm/0ZH0HtQO9u3l//yjtHUpjeRjjPGfGRI= diff --git a/mihomo/listener/sing_tun/server.go b/mihomo/listener/sing_tun/server.go index 2dc6524ee3..09bf308c73 100644 --- a/mihomo/listener/sing_tun/server.go +++ b/mihomo/listener/sing_tun/server.go @@ -59,15 +59,23 @@ func CalculateInterfaceName(name string) (tunName string) { if err != nil { return } - var tunIndex int + tunIndex := 0 + indexSet := make(map[int]struct{}) for _, netInterface := range interfaces { if strings.HasPrefix(netInterface.Name, tunName) { index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16) if parseErr == nil { - tunIndex = int(index) + 1 + indexSet[int(index)] = struct{}{} } } } + for index := range indexSet { + if index == tunIndex { + tunIndex += 1 + } else { // indexSet already sorted and distinct, so this tunIndex nobody used + break + } + } tunName = F.ToString(tunName, tunIndex) return } diff --git a/mihomo/listener/tproxy/packet.go b/mihomo/listener/tproxy/packet.go index e485266515..b038d954f8 100644 --- a/mihomo/listener/tproxy/packet.go +++ b/mihomo/listener/tproxy/packet.go @@ -105,9 +105,9 @@ func listenLocalConn(rAddr, lAddr net.Addr, tunnel C.Tunnel) (*net.UDPConn, erro buf := pool.Get(pool.UDPBufferSize) br, err := lc.Read(buf) if err != nil { - pool.Put(buf) if errors.Is(err, net.ErrClosed) { log.Debugln("TProxy local conn listener exit.. rAddr=%s lAddr=%s", rAddr.String(), lAddr.String()) + pool.Put(buf) return } } diff --git a/openwrt-packages/adguardhome/Makefile b/openwrt-packages/adguardhome/Makefile index 8abe1cb964..e2f8dbba81 100644 --- a/openwrt-packages/adguardhome/Makefile +++ b/openwrt-packages/adguardhome/Makefile @@ -6,12 +6,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=adguardhome -PKG_VERSION:=0.107.48 +PKG_VERSION:=0.107.49 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/AdguardTeam/AdGuardHome/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=189afe8ccc4efd229c3554d812f590cc8727e966c05a6129d444c88a905b83a1 +PKG_HASH:=eb1e6ba1d7ffce47fde8abaec25e7cc6a6467145073370d44be20ec3719698ef PKG_LICENSE:=GPL-3.0-only PKG_LICENSE_FILES:=LICENSE.txt @@ -57,7 +57,7 @@ define Download/adguardhome-frontend URL:=https://github.com/AdguardTeam/AdGuardHome/releases/download/v$(PKG_VERSION)/ URL_FILE:=AdGuardHome_frontend.tar.gz FILE:=$(FRONTEND_FILE) - HASH:=48670d085bbdd7a70f4a4cbcba047dd94052190c5471ada5be92c334ed793aa2 + HASH:=554e71adf83f7050a9affbc9671697cc6515bca760af1493874e9b8ab69c9ec2 endef define Build/Prepare diff --git a/openwrt-packages/luci-app-store/Makefile b/openwrt-packages/luci-app-store/Makefile index 319b2651eb..f9af2c3b9c 100644 --- a/openwrt-packages/luci-app-store/Makefile +++ b/openwrt-packages/luci-app-store/Makefile @@ -11,7 +11,7 @@ LUCI_DEPENDS:=+curl +opkg +luci-base +tar +coreutils +coreutils-stat +libuci-lua LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.17) LUCI_PKGARCH:=all -PKG_VERSION:=0.1.14-3 +PKG_VERSION:=0.1.16-1 # PKG_RELEASE MUST be empty for luci.mk PKG_RELEASE:= diff --git a/openwrt-packages/luci-app-store/root/bin/is-opkg b/openwrt-packages/luci-app-store/root/bin/is-opkg index 5bc97ae65d..d89470719d 100755 --- a/openwrt-packages/luci-app-store/root/bin/is-opkg +++ b/openwrt-packages/luci-app-store/root/bin/is-opkg @@ -7,7 +7,10 @@ DL_DIR=${IS_ROOT}/tmp/dl LISTS_DIR_O=/tmp/opkg-lists LISTS_DIR=${IS_ROOT}${LISTS_DIR_O} OPKG_CONF_DIR=${IS_ROOT}/etc/opkg +OPKG_CONF_DIR_M=${IS_ROOT}/etc/opkg_m FEEDS_SERVER=https://istore.linkease.com/repo +FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo" +DISABLE_MIRROR=false ARCH=`sed -n -e 's/^Architecture: *\([^ ]\+\) *$/\1/p' /rom/usr/lib/opkg/info/libc.control /usr/lib/opkg/info/libc.control 2>/dev/null | head -1` # for istore self upgrade @@ -39,10 +42,33 @@ opkg_wrap() { OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" } -fcurl() { - curl --fail --show-error "$@" +opkg_wrap_mirrors() { + local server + local file + if ! $DISABLE_MIRROR; then + for server in $FEEDS_SERVER_MIRRORS ; do + rm -rf "${OPKG_CONF_DIR_M}" 2>/dev/null + mkdir -p "${OPKG_CONF_DIR_M}" 2>/dev/null + ls "${OPKG_CONF_DIR}/" | while read; do + file="$REPLY" + if [ -f "${OPKG_CONF_DIR}/$file" -a "${file: -5}" = ".conf" ]; then + sed "s#$FEEDS_SERVER/#$server/#g" "${OPKG_CONF_DIR}/$file" >"${OPKG_CONF_DIR_M}/$file" + touch -r "${OPKG_CONF_DIR}/$file" "${OPKG_CONF_DIR_M}/$file" 2>/dev/null + else + cp -a "${OPKG_CONF_DIR}/$file" "${OPKG_CONF_DIR_M}/" + fi + done + echo "Try mirror server $server" + OPKG_CONF_DIR=${OPKG_CONF_DIR_M} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" && return 0 + done + DISABLE_MIRROR=true + fi + echo "Try origin server $FEEDS_SERVER" + OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" } +alias fcurl='curl -L --fail --show-error' + check_space() { local free="$((`stat -c '%a * %S' -f /` >> 20 ))" if [ "$free" -lt 1 ]; then @@ -140,10 +166,10 @@ step_upgrade() { fi done if [ -n "$pkgs" ]; then - opkg_wrap upgrade $pkgs || return 1 + opkg_wrap_mirrors upgrade $pkgs || return 1 fi if [ -n "$metapkg" ]; then - opkg_wrap upgrade $metapkg || return 1 + opkg_wrap_mirrors upgrade $metapkg || return 1 fi return 0 } @@ -186,7 +212,7 @@ case $action in ;; "install") check_space - wrapped_in_update opkg_wrap install "$@" + wrapped_in_update opkg_wrap_mirrors install "$@" ;; "upgrade") new_upgrade "$@" diff --git a/ryujinx/Directory.Packages.props b/ryujinx/Directory.Packages.props index d04e237e04..739e66bd0e 100644 --- a/ryujinx/Directory.Packages.props +++ b/ryujinx/Directory.Packages.props @@ -11,7 +11,7 @@ - + @@ -49,4 +49,4 @@ - + \ No newline at end of file diff --git a/ryujinx/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj b/ryujinx/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj index d1f572d5c8..bf34ddd17a 100644 --- a/ryujinx/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj +++ b/ryujinx/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -16,10 +16,4 @@ - - - - NU1605 - - diff --git a/ryujinx/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoder.cs b/ryujinx/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoder.cs index 5d27985826..2146362dfc 100644 --- a/ryujinx/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoder.cs +++ b/ryujinx/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoder.cs @@ -14,6 +14,11 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail { partial class HardwareOpusDecoder : IHardwareOpusDecoder, IDisposable { + static HardwareOpusDecoder() + { + OpusCodecFactory.AttemptToUseNativeLibrary = false; + } + [StructLayout(LayoutKind.Sequential)] private struct OpusPacketHeader { @@ -30,60 +35,87 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail } } - private interface IDecoder + private interface IDecoder : IDisposable { int SampleRate { get; } int ChannelsCount { get; } - int Decode(byte[] inData, int inDataOffset, int len, short[] outPcm, int outPcmOffset, int frameSize); + int Decode(ReadOnlySpan inData, Span outPcm, int frameSize); void ResetState(); } private class Decoder : IDecoder { - private readonly OpusDecoder _decoder; + private readonly IOpusDecoder _decoder; public int SampleRate => _decoder.SampleRate; public int ChannelsCount => _decoder.NumChannels; public Decoder(int sampleRate, int channelsCount) { - _decoder = new OpusDecoder(sampleRate, channelsCount); + _decoder = OpusCodecFactory.CreateDecoder(sampleRate, channelsCount); } - public int Decode(byte[] inData, int inDataOffset, int len, short[] outPcm, int outPcmOffset, int frameSize) + public int Decode(ReadOnlySpan inData, Span outPcm, int frameSize) { - return _decoder.Decode(inData, inDataOffset, len, outPcm, outPcmOffset, frameSize); + return _decoder.Decode(inData, outPcm, frameSize); } public void ResetState() { _decoder.ResetState(); } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _decoder?.Dispose(); + } + } } private class MultiSampleDecoder : IDecoder { - private readonly OpusMSDecoder _decoder; + private readonly IOpusMultiStreamDecoder _decoder; public int SampleRate => _decoder.SampleRate; - public int ChannelsCount { get; } + public int ChannelsCount => _decoder.NumChannels; public MultiSampleDecoder(int sampleRate, int channelsCount, int streams, int coupledStreams, byte[] mapping) { - ChannelsCount = channelsCount; - _decoder = new OpusMSDecoder(sampleRate, channelsCount, streams, coupledStreams, mapping); + _decoder = OpusCodecFactory.CreateMultiStreamDecoder(sampleRate, channelsCount, streams, coupledStreams, mapping); } - public int Decode(byte[] inData, int inDataOffset, int len, short[] outPcm, int outPcmOffset, int frameSize) + public int Decode(ReadOnlySpan inData, Span outPcm, int frameSize) { - return _decoder.DecodeMultistream(inData, inDataOffset, len, outPcm, outPcmOffset, frameSize, 0); + return _decoder.DecodeMultistream(inData, outPcm, frameSize, false); } public void ResetState() { _decoder.ResetState(); } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _decoder?.Dispose(); + } + } } private readonly IDecoder _decoder; @@ -221,7 +253,8 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail { timeTaken = 0; - Result result = DecodeInterleaved(_decoder, reset, input, out short[] outPcmData, output.Length, out outConsumed, out outSamples); + Span outPcmSpace = MemoryMarshal.Cast(output); + Result result = DecodeInterleaved(_decoder, reset, input, outPcmSpace, output.Length, out outConsumed, out outSamples); if (withPerf) { @@ -229,14 +262,12 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail timeTaken = 0; } - MemoryMarshal.Cast(outPcmData).CopyTo(output[..(outPcmData.Length * sizeof(short))]); - return result; } - private static Result GetPacketNumSamples(IDecoder decoder, out int numSamples, byte[] packet) + private static Result GetPacketNumSamples(IDecoder decoder, out int numSamples, ReadOnlySpan packet) { - int result = OpusPacketInfo.GetNumSamples(packet, 0, packet.Length, decoder.SampleRate); + int result = OpusPacketInfo.GetNumSamples(packet, decoder.SampleRate); numSamples = result; @@ -256,12 +287,11 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail IDecoder decoder, bool reset, ReadOnlySpan input, - out short[] outPcmData, + Span outPcmData, int outputSize, out int outConsumed, out int outSamples) { - outPcmData = null; outConsumed = 0; outSamples = 0; @@ -281,7 +311,7 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail return CodecResult.InvalidLength; } - byte[] opusData = input.Slice(headerSize, (int)header.Length).ToArray(); + ReadOnlySpan opusData = input.Slice(headerSize, (int)header.Length); Result result = GetPacketNumSamples(decoder, out int numSamples, opusData); @@ -292,8 +322,6 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail return CodecResult.InvalidLength; } - outPcmData = new short[numSamples * decoder.ChannelsCount]; - if (reset) { decoder.ResetState(); @@ -301,13 +329,22 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail try { - outSamples = decoder.Decode(opusData, 0, opusData.Length, outPcmData, 0, outPcmData.Length / decoder.ChannelsCount); + outSamples = decoder.Decode(opusData, outPcmData, numSamples); outConsumed = (int)totalSize; } - catch (OpusException) + catch (OpusException e) { - // TODO: As OpusException doesn't return the exact error code, this is inaccurate in some cases... - return CodecResult.InvalidLength; + switch (e.OpusErrorCode) + { + case OpusError.OPUS_BUFFER_TOO_SMALL: + return CodecResult.InvalidLength; + case OpusError.OPUS_BAD_ARG: + return CodecResult.OpusBadArg; + case OpusError.OPUS_INVALID_PACKET: + return CodecResult.OpusInvalidPacket; + default: + return CodecResult.InvalidLength; + } } } @@ -324,6 +361,8 @@ namespace Ryujinx.Horizon.Sdk.Codec.Detail _workBufferHandle = 0; } + + _decoder?.Dispose(); } } diff --git a/sing-box/docs/changelog.md b/sing-box/docs/changelog.md index 03e77a4ffa..5c070ff86e 100644 --- a/sing-box/docs/changelog.md +++ b/sing-box/docs/changelog.md @@ -2,6 +2,10 @@ icon: material/alert-decagram --- +#### 1.9.0-rc.21 + +* Fixes and improvements + #### 1.9.0-rc.20 * Prioritize `*_route_address` in linux auto-route diff --git a/sing-box/go.mod b/sing-box/go.mod index 2d2ac21785..1bb9375c2d 100644 --- a/sing-box/go.mod +++ b/sing-box/go.mod @@ -26,7 +26,7 @@ require ( github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f github.com/sagernet/quic-go v0.43.1-beta.1 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 - github.com/sagernet/sing v0.4.0-beta.19 + github.com/sagernet/sing v0.4.0-beta.20 github.com/sagernet/sing-dns v0.2.0-beta.18 github.com/sagernet/sing-mux v0.2.0 github.com/sagernet/sing-quic v0.2.0-beta.5 diff --git a/sing-box/go.sum b/sing-box/go.sum index 6ee22b69b1..689c57d64e 100644 --- a/sing-box/go.sum +++ b/sing-box/go.sum @@ -106,8 +106,8 @@ github.com/sagernet/quic-go v0.43.1-beta.1/go.mod h1:BkrQYeop7Jx3hN3TW8/76CXcdhY github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= -github.com/sagernet/sing v0.4.0-beta.19 h1:Kzh2f6eaxt09S+bEL8F4Bgy03qkNf+4Tt8g7/5lxp/o= -github.com/sagernet/sing v0.4.0-beta.19/go.mod h1:PFQKbElc2Pke7faBLv8oEba5ehtKO21Ho+TkYemTI3Y= +github.com/sagernet/sing v0.4.0-beta.20 h1:8rEepj4LMcR0Wd389fJIziv/jr3MBtX5qXBHsfxJ+dY= +github.com/sagernet/sing v0.4.0-beta.20/go.mod h1:PFQKbElc2Pke7faBLv8oEba5ehtKO21Ho+TkYemTI3Y= github.com/sagernet/sing-dns v0.2.0-beta.18 h1:6vzXZThRdA7YUzBOpSbUT48XRumtl/KIpIHFSOP0za8= github.com/sagernet/sing-dns v0.2.0-beta.18/go.mod h1:k/dmFcQpg6+m08gC1yQBy+13+QkuLqpKr4bIreq4U24= github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo= diff --git a/small/v2ray-geodata/Makefile b/small/v2ray-geodata/Makefile index 1f372612c1..bec128c255 100644 --- a/small/v2ray-geodata/Makefile +++ b/small/v2ray-geodata/Makefile @@ -30,13 +30,13 @@ define Download/geosite HASH:=25d6120b009498ac83ae723e9751a19ff545fac4800dad53ab6e2592c3407533 endef -GEOSITE_IRAN_VER:=202405200027 +GEOSITE_IRAN_VER:=202405201648 GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER) define Download/geosite-ir URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/ URL_FILE:=iran.dat FILE:=$(GEOSITE_IRAN_FILE) - HASH:=19b8a3aa46f5ce3543f9e3ebe64ad3437ce02189ba67be4d7931d7babdf42a84 + HASH:=8c37d450d8b756fcc58e71eeef67d4db419c05216259c177bd2cf01c55851d67 endef define Package/v2ray-geodata/template diff --git a/suyu/README.md b/suyu/README.md index a423a83169..6fa5ed4d2e 100644 --- a/suyu/README.md +++ b/suyu/README.md @@ -9,7 +9,6 @@ SPDX-License-Identifier: GPL-3.0-or-later We're in need of developers. Please join our chat below if you want to contribute! This repo was based on Yuzu EA 4176 but the code is being rewritten from the ground up for legal and performance reasons. -Support the original suyu developer team [here](https://discord.gg/79B6wqFPnc).
diff --git a/yt-dlp/README.md b/yt-dlp/README.md index cdd57b024c..1029d1a6d9 100644 --- a/yt-dlp/README.md +++ b/yt-dlp/README.md @@ -263,7 +263,7 @@ You can also run `make yt-dlp` instead to compile only the binary without updati ### Standalone Py2Exe Builds (Windows) -While we provide the option to build with [py2exe](https://www.py2exe.org), it is recommended to build [using PyInstaller](#standalone-pyinstaller-builds) instead since the py2exe builds **cannot contain `pycryptodomex`/`certifi` and needs VC++14** on the target computer to run. +While we provide the option to build with [py2exe](https://www.py2exe.org), it is recommended to build [using PyInstaller](#standalone-pyinstaller-builds) instead since the py2exe builds **cannot contain `pycryptodomex`/`certifi`/`requests` and need VC++14** on the target computer to run. If you wish to build it anyway, install Python (if it is not already installed) and you can run the following commands: @@ -1815,6 +1815,7 @@ The following extractors use this feature: * `manifest_app_version`: Default numeric app version to use with mobile API calls, e.g. `2023401020` * `aid`: Default app ID to use with mobile API calls, e.g. `1180` * `app_info`: Enable mobile API extraction with one or more app info strings in the format of `/[app_name]/[app_version]/[manifest_app_version]/[aid]`, where `iid` is the unique app install ID. `iid` is the only required value; all other values and their `/` separators can be omitted, e.g. `tiktok:app_info=1234567890123456789` or `tiktok:app_info=123,456/trill///1180,789//34.0.1/340001` +* `device_id`: Enable mobile API extraction with a genuine device ID to be used with mobile API calls. Default is a random 19-digit string #### rokfinchannel * `tab`: Which tab to download - one of `new`, `top`, `videos`, `podcasts`, `streams`, `stacks` diff --git a/yt-dlp/bundle/py2exe.py b/yt-dlp/bundle/py2exe.py index 2811674925..403de00241 100755 --- a/yt-dlp/bundle/py2exe.py +++ b/yt-dlp/bundle/py2exe.py @@ -42,9 +42,9 @@ def main(): # py2exe cannot import Crypto 'Crypto', 'Cryptodome', - # py2exe appears to confuse this with our socks library. - # We don't use pysocks and urllib3.contrib.socks would fail to import if tried. - 'urllib3.contrib.socks' + # py2exe builds fail to run with requests >=2.32.0 + 'requests', + 'urllib3' ], 'dll_excludes': ['w9xpopen.exe', 'crypt32.dll'], # Modules that are only imported dynamically must be added here diff --git a/yt-dlp/pyproject.toml b/yt-dlp/pyproject.toml index 5fadd14495..74d7ff323f 100644 --- a/yt-dlp/pyproject.toml +++ b/yt-dlp/pyproject.toml @@ -46,7 +46,7 @@ dependencies = [ "certifi", "mutagen", "pycryptodomex", - "requests>=2.31.0,<3", + "requests>=2.32.0,<3", "urllib3>=1.26.17,<3", "websockets>=12.0", ] diff --git a/yt-dlp/yt_dlp/extractor/tiktok.py b/yt-dlp/yt_dlp/extractor/tiktok.py index 2fb41ba794..c96fa50388 100644 --- a/yt-dlp/yt_dlp/extractor/tiktok.py +++ b/yt-dlp/yt_dlp/extractor/tiktok.py @@ -1,8 +1,8 @@ +import functools import itertools import json import random import re -import string import time import uuid @@ -15,10 +15,13 @@ from ..utils import ( UnsupportedError, UserNotLive, determine_ext, + filter_dict, format_field, int_or_none, join_nonempty, merge_dicts, + mimetype2ext, + parse_qs, qualities, remove_start, srt_subtitles_timecode, @@ -49,11 +52,21 @@ class TikTokBaseIE(InfoExtractor): _APP_INFO = None _APP_USER_AGENT = None - @property + @functools.cached_property def _KNOWN_APP_INFO(self): - return self._configuration_arg('app_info', ie_key=TikTokIE) + # If we have a genuine device ID, we may not need any IID + default = [''] if self._KNOWN_DEVICE_ID else [] + return self._configuration_arg('app_info', default, ie_key=TikTokIE) - @property + @functools.cached_property + def _KNOWN_DEVICE_ID(self): + return self._configuration_arg('device_id', [None], ie_key=TikTokIE)[0] + + @functools.cached_property + def _DEVICE_ID(self): + return self._KNOWN_DEVICE_ID or str(random.randint(7250000000000000000, 7351147085025500000)) + + @functools.cached_property def _API_HOSTNAME(self): return self._configuration_arg( 'api_hostname', ['api16-normal-c-useast1a.tiktokv.com'], ie_key=TikTokIE)[0] @@ -115,7 +128,7 @@ class TikTokBaseIE(InfoExtractor): }, query=query) def _build_api_query(self, query): - return { + return filter_dict({ **query, 'device_platform': 'android', 'os': 'android', @@ -156,10 +169,10 @@ class TikTokBaseIE(InfoExtractor): 'build_number': self._APP_INFO['app_version'], 'region': 'US', 'ts': int(time.time()), - 'iid': self._APP_INFO['iid'], - 'device_id': random.randint(7250000000000000000, 7351147085025500000), + 'iid': self._APP_INFO.get('iid'), + 'device_id': self._DEVICE_ID, 'openudid': ''.join(random.choices('0123456789abcdef', k=16)), - } + }) def _call_api(self, ep, query, video_id, fatal=True, note='Downloading API JSON', errnote='Unable to download API page'): @@ -239,23 +252,22 @@ class TikTokBaseIE(InfoExtractor): }) return subtitles + def _parse_url_key(self, url_key): + format_id, codec, res, bitrate = self._search_regex( + r'v[^_]+_(?P(?P[^_]+)_(?P\d+p)_(?P\d+))', url_key, + 'url key', default=(None, None, None, None), group=('id', 'codec', 'res', 'bitrate')) + if not format_id: + return {}, None + return { + 'format_id': format_id, + 'vcodec': 'h265' if codec == 'bytevc1' else codec, + 'tbr': int_or_none(bitrate, scale=1000) or None, + 'quality': qualities(self.QUALITIES)(res), + }, res + def _parse_aweme_video_app(self, aweme_detail): aweme_id = aweme_detail['aweme_id'] video_info = aweme_detail['video'] - - def parse_url_key(url_key): - format_id, codec, res, bitrate = self._search_regex( - r'v[^_]+_(?P(?P[^_]+)_(?P\d+p)_(?P\d+))', url_key, - 'url key', default=(None, None, None, None), group=('id', 'codec', 'res', 'bitrate')) - if not format_id: - return {}, None - return { - 'format_id': format_id, - 'vcodec': 'h265' if codec == 'bytevc1' else codec, - 'tbr': int_or_none(bitrate, scale=1000) or None, - 'quality': qualities(self.QUALITIES)(res), - }, res - known_resolutions = {} def audio_meta(url): @@ -270,7 +282,7 @@ class TikTokBaseIE(InfoExtractor): } if ext == 'mp3' or '-music-' in url else {} def extract_addr(addr, add_meta={}): - parsed_meta, res = parse_url_key(addr.get('url_key', '')) + parsed_meta, res = self._parse_url_key(addr.get('url_key', '')) is_bytevc2 = parsed_meta.get('vcodec') == 'bytevc2' if res: known_resolutions.setdefault(res, {}).setdefault('height', int_or_none(addr.get('height'))) @@ -284,7 +296,7 @@ class TikTokBaseIE(InfoExtractor): 'acodec': 'aac', 'source_preference': -2 if 'aweme/v1' in url else -1, # Downloads from API might get blocked **add_meta, **parsed_meta, - # bytevc2 is bytedance's proprietary (unplayable) video codec + # bytevc2 is bytedance's own custom h266/vvc codec, as-of-yet unplayable 'preference': -100 if is_bytevc2 else -1, 'format_note': join_nonempty( add_meta.get('format_note'), '(API)' if 'aweme/v1' in url else None, @@ -296,6 +308,7 @@ class TikTokBaseIE(InfoExtractor): formats = [] width = int_or_none(video_info.get('width')) height = int_or_none(video_info.get('height')) + ratio = try_call(lambda: width / height) or 0.5625 if video_info.get('play_addr'): formats.extend(extract_addr(video_info['play_addr'], { 'format_id': 'play_addr', @@ -312,8 +325,8 @@ class TikTokBaseIE(InfoExtractor): 'format_id': 'download_addr', 'format_note': 'Download video%s' % (', watermarked' if video_info.get('has_watermark') else ''), 'vcodec': 'h264', - 'width': dl_width or width, - 'height': try_call(lambda: int(dl_width / 0.5625)) or height, # download_addr['height'] is wrong + 'width': dl_width, + 'height': try_call(lambda: int(dl_width / ratio)), # download_addr['height'] is wrong 'preference': -2 if video_info.get('has_watermark') else -1, })) if video_info.get('play_addr_h264'): @@ -420,26 +433,88 @@ class TikTokBaseIE(InfoExtractor): formats = [] width = int_or_none(video_info.get('width')) height = int_or_none(video_info.get('height')) + ratio = try_call(lambda: width / height) or 0.5625 + COMMON_FORMAT_INFO = { + 'ext': 'mp4', + 'vcodec': 'h264', + 'acodec': 'aac', + } + + for bitrate_info in traverse_obj(video_info, ('bitrateInfo', lambda _, v: v['PlayAddr']['UrlList'])): + format_info, res = self._parse_url_key( + traverse_obj(bitrate_info, ('PlayAddr', 'UrlKey', {str})) or '') + # bytevc2 is bytedance's own custom h266/vvc codec, as-of-yet unplayable + is_bytevc2 = format_info.get('vcodec') == 'bytevc2' + format_info.update({ + 'format_note': 'UNPLAYABLE' if is_bytevc2 else None, + 'preference': -100 if is_bytevc2 else -1, + 'filesize': traverse_obj(bitrate_info, ('PlayAddr', 'DataSize', {int_or_none})), + }) + + if dimension := (res and int(res[:-1])): + if dimension == 540: # '540p' is actually 576p + dimension = 576 + if ratio < 1: # portrait: res/dimension is width + y = int(dimension / ratio) + format_info.update({ + 'width': dimension, + 'height': y - (y % 2), + }) + else: # landscape: res/dimension is height + x = int(dimension * ratio) + format_info.update({ + 'width': x - (x % 2), + 'height': dimension, + }) + + for video_url in traverse_obj(bitrate_info, ('PlayAddr', 'UrlList', ..., {url_or_none})): + formats.append({ + **COMMON_FORMAT_INFO, + **format_info, + 'url': self._proto_relative_url(video_url), + }) + + # We don't have res string for play formats, but need quality for sorting & de-duplication + play_quality = traverse_obj(formats, (lambda _, v: v['width'] == width, 'quality', any)) for play_url in traverse_obj(video_info, ('playAddr', ((..., 'src'), None), {url_or_none})): formats.append({ + **COMMON_FORMAT_INFO, + 'format_id': 'play', 'url': self._proto_relative_url(play_url), - 'ext': 'mp4', 'width': width, 'height': height, + 'quality': play_quality, }) for download_url in traverse_obj(video_info, (('downloadAddr', ('download', 'url')), {url_or_none})): formats.append({ + **COMMON_FORMAT_INFO, 'format_id': 'download', 'url': self._proto_relative_url(download_url), - 'ext': 'mp4', - 'width': width, - 'height': height, }) self._remove_duplicate_formats(formats) + for f in traverse_obj(formats, lambda _, v: 'unwatermarked' not in v['url']): + f.update({ + 'format_note': join_nonempty(f.get('format_note'), 'watermarked', delim=', '), + 'preference': f.get('preference') or -2, + }) + + # Is it a slideshow with only audio for download? + if not formats and traverse_obj(music_info, ('playUrl', {url_or_none})): + audio_url = music_info['playUrl'] + ext = traverse_obj(parse_qs(audio_url), ( + 'mime_type', -1, {lambda x: x.replace('_', '/')}, {mimetype2ext})) or 'm4a' + formats.append({ + 'format_id': 'audio', + 'url': self._proto_relative_url(audio_url), + 'ext': ext, + 'acodec': 'aac' if ext == 'm4a' else ext, + 'vcodec': 'none', + }) + thumbnails = [] for thumb_url in traverse_obj(aweme_detail, ( (None, 'video'), ('thumbnail', 'cover', 'dynamicCover', 'originCover'), {url_or_none})): @@ -451,10 +526,17 @@ class TikTokBaseIE(InfoExtractor): return { 'id': video_id, + **traverse_obj(music_info, { + 'track': ('title', {str}), + 'album': ('album', {str}, {lambda x: x or None}), + 'artists': ('authorName', {str}, {lambda x: [x] if x else None}), + 'duration': ('duration', {int_or_none}), + }), **traverse_obj(aweme_detail, { 'title': ('desc', {str}), 'description': ('desc', {str}), - 'duration': ('video', 'duration', {int_or_none}), + # audio-only slideshows have a video duration of 0 and an actual audio duration + 'duration': ('video', 'duration', {int_or_none}, {lambda x: x or None}), 'timestamp': ('createTime', {int_or_none}), }), **traverse_obj(author_info or aweme_detail, { @@ -469,11 +551,6 @@ class TikTokBaseIE(InfoExtractor): 'repost_count': 'shareCount', 'comment_count': 'commentCount', }, expected_type=int_or_none), - **traverse_obj(music_info, { - 'track': ('title', {str}), - 'album': ('album', {str}, {lambda x: x or None}), - 'artists': ('authorName', {str}, {lambda x: [x] if x else None}), - }), 'channel_id': channel_id, 'uploader_url': user_url, 'formats': formats, @@ -848,7 +925,7 @@ class TikTokUserIE(TikTokBaseIE): 'max_cursor': 0, 'min_cursor': 0, 'retry_type': 'no_retry', - 'device_id': ''.join(random.choices(string.digits, k=19)), # Some endpoints don't like randomized device_id, so it isn't directly set in _call_api. + 'device_id': self._DEVICE_ID, # Some endpoints don't like randomized device_id, so it isn't directly set in _call_api. } for page in itertools.count(1): @@ -896,7 +973,7 @@ class TikTokBaseListIE(TikTokBaseIE): # XXX: Conventionally, base classes shoul 'cursor': 0, 'count': 20, 'type': 5, - 'device_id': ''.join(random.choices(string.digits, k=19)) + 'device_id': self._DEVICE_ID, } for page in itertools.count(1): diff --git a/yt-dlp/yt_dlp/networking/_requests.py b/yt-dlp/yt_dlp/networking/_requests.py index e3edc77f38..75eee88246 100644 --- a/yt-dlp/yt_dlp/networking/_requests.py +++ b/yt-dlp/yt_dlp/networking/_requests.py @@ -21,8 +21,8 @@ urllib3_version = tuple(int_or_none(x, default=0) for x in urllib3.__version__.s if urllib3_version < (1, 26, 17): raise ImportError('Only urllib3 >= 1.26.17 is supported') -if requests.__build__ < 0x023100: - raise ImportError('Only requests >= 2.31.0 is supported') +if requests.__build__ < 0x023200: + raise ImportError('Only requests >= 2.32.0 is supported') import requests.adapters import requests.utils @@ -181,9 +181,13 @@ class RequestsHTTPAdapter(requests.adapters.HTTPAdapter): return super().proxy_manager_for(proxy, **proxy_kwargs, **self._pm_args, **extra_kwargs) def cert_verify(*args, **kwargs): - # lean on SSLContext for cert verification + # Lean on our SSLContext for cert verification pass + def _get_connection(self, request, *_, proxies=None, **__): + # Lean on our SSLContext for cert verification + return self.get_connection(request.url, proxies) + class RequestsSession(requests.sessions.Session): """