diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..4d3e59dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[Bug] " +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '...' +3. Scroll down to '...' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..cb9961c7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Feature] " +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4afb0db7..de7784f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,7 @@ jobs: IFS="." read -r -a VERSION_ARRAY <<< "${github_ref_name#v}" VERSION_STR="${VERSION_ARRAY[0]}.${VERSION_ARRAY[1]}.${VERSION_ARRAY[2]}" sed -i "s|PKG_VERSION:=.*|PKG_VERSION:=${VERSION_STR}|g" wrt/Makefile - sed -i "s|PKG_HASH:=.*|PKG_HASH:=${HIDDIFY_CORE_WRT_HASH}|g" wrt/Makefile + sed -i "s|PKG_HASH:=.*|PKG_HASH:=${HIDDIFY_CORE_WRT_HASH}|g" wrt/Makefile - uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: "Update WRT package HASH." @@ -43,26 +43,26 @@ jobs: matrix: job: - { name: 'hiddify-core-android', os: 'ubuntu-latest', target: 'android' } - - { name: 'hiddify-core-linux-amd64', os: 'ubuntu-20.04', target: 'linux-amd64' } + - { name: 'hiddify-core-linux-amd64', os: 'ubuntu-22.04', target: 'linux-amd64' } - { name: "hiddify-core-windows-amd64", os: 'ubuntu-latest', target: 'windows-amd64', aarch: 'x64' } - { name: "hiddify-core-macos-universal", os: 'macos-12', target: 'macos-universal' } - { name: "hiddify-core-ios", os: "macos-12", target: "ios" } # linux custom - - {name: hiddify-cli-linux-amd64, goos: linux, goarch: amd64, goamd64: v1, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-amd64-v3, goos: linux, goarch: amd64, goamd64: v3, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-386, goos: linux, goarch: 386, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-arm64, goos: linux, goarch: arm64, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-armv5, goos: linux, goarch: arm, goarm: 5, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-armv6, goos: linux, goarch: arm, goarm: 6, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-armv7, goos: linux, goarch: arm, goarm: 7, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-mips-softfloat, goos: linux, goarch: mips, gomips: softfloat, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-mips-hardfloat, goos: linux, goarch: mips, gomips: hardfloat, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-mipsel-softfloat, goos: linux, goarch: mipsle, gomips: softfloat, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-mipsel-hardfloat, goos: linux, goarch: mipsle, gomips: hardfloat, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-mips64, goos: linux, goarch: mips64, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-mips64el, goos: linux, goarch: mips64le, target: 'linux-custom', os: 'ubuntu-20.04'} - - {name: hiddify-cli-linux-s390x, goos: linux, goarch: s390x, target: 'linux-custom', os: 'ubuntu-20.04'} - + - {name: hiddify-cli-linux-amd64, goos: linux, goarch: amd64, goamd64: v1, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-amd64-v3, goos: linux, goarch: amd64, goamd64: v3, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-386, goos: linux, goarch: 386, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-arm64, goos: linux, goarch: arm64, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-armv5, goos: linux, goarch: arm, goarm: 5, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-armv6, goos: linux, goarch: arm, goarm: 6, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-armv7, goos: linux, goarch: arm, goarm: 7, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-mips-softfloat, goos: linux, goarch: mips, gomips: softfloat, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-mips-hardfloat, goos: linux, goarch: mips, gomips: hardfloat, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-mipsel-softfloat, goos: linux, goarch: mipsle, gomips: softfloat, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-mipsel-hardfloat, goos: linux, goarch: mipsle, gomips: hardfloat, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-mips64, goos: linux, goarch: mips64, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-mips64el, goos: linux, goarch: mips64le, target: 'linux-custom', os: 'ubuntu-22.04'} + - {name: hiddify-cli-linux-s390x, goos: linux, goarch: s390x, target: 'linux-custom', os: 'ubuntu-22.04'} + runs-on: ${{ matrix.job.os }} env: GOOS: ${{ matrix.job.goos }} @@ -115,14 +115,14 @@ jobs: - name: zip run: | - tree + tree rm -f /*.h */*.h rm ./hiddify-libcore*sources* ||echo "no source" rm ./hiddify-libcore-macos-a*.dylib || echo "no macos arm and amd" files=$(ls | grep -E '^(libcore\.(dll|so|dylib|aar)|webui|Libcore.xcframework|lib|HiddifyCli(\.exe)?)$') echo tar -czvf ${{ matrix.job.name }}.tar.gz $files tar -czvf ${{ matrix.job.name }}.tar.gz $files - + working-directory: bin - uses: actions/upload-artifact@v4 if: ${{ success() }} @@ -206,7 +206,7 @@ jobs: permissions: write-all if: ${{ inputs.channel=='prod' }} needs: [upload-release] - + runs-on: ubuntu-latest strategy: fail-fast: true @@ -297,7 +297,7 @@ jobs: -t "${{ env.REGISTRY_IMAGE }}:${{ inputs.tag-name }}" \ $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) - name: Inspect image - + run: | docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ env.LATEST }} docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ inputs.tag-name }} diff --git a/.gitignore b/.gitignore index 545c18c3..9def7f58 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ cert **/*.syso node_modules *.db -*.json \ No newline at end of file +*.json +*.tar.gz +hiddify-cli.exe \ No newline at end of file diff --git a/Makefile b/Makefile index 45213b0d..b39a15d7 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,8 @@ protos: lib_install: - go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.1 - go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.1 + go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.8 + go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.8 npm install headers: diff --git a/README.md b/README.md index f5392d11..741d1681 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,25 @@ # hiddify-core - ## Docker -To Run our docker image see https://github.com/hiddify/hiddify-core/pkgs/container/hiddify-core + +To Run our docker image see Docker -``` + +```bash docker pull ghcr.io/hiddify/hiddify-core:latest ``` Docker Compose -``` + +```bash git clone https://github.com/hiddify/hiddify-core cd hiddify-core/docker docker-compose up ``` ## WRT + ... ## Extension @@ -31,23 +34,70 @@ Features and Road map: - [x] Add Third Party Extension capability - [x] Test Extension from Browser without any dependency to android/mac/.... `./cmd.sh extension` the open browser `https://127.0.0.1:12346` -- [x] Show Custom UI from Extension `github.com/hiddify/hiddify-core/extension.UpdateUI()` +- [x] Show Custom UI from Extension `github.com/hiddify/hiddify-core/extension.UpdateUI()` - [x] Show Custom Dialog from Extension `github.com/hiddify/hiddify-core/extension.ShowDialog()` -- [x] Show Alert Dialog from Extension `github.com/hiddify/hiddify-core/extension.ShowMessage()` -- [x] Get Data from UI `github.com/hiddify/hiddify-core/extension.SubmitData()` +- [x] Show Alert Dialog from Extension `github.com/hiddify/hiddify-core/extension.ShowMessage()` +- [x] Get Data from UI `github.com/hiddify/hiddify-core/extension.SubmitData()` - [x] Save Extension Data from `e.Base.Data` - [x] Load Extension Data to `e.Base.Data` -- [x] Disable / Enable Extension -- [x] Update user proxies before connecting `github.com/hiddify/hiddify-core/extension.BeforeAppConnect()` -- [x] Run Tiny Independent Instance `github.com/hiddify/hiddify-core/extension/sdk.RunInstance()` -- [x] Parse Any type of configs/url `github.com/hiddify/hiddify-core/extension/sdk.ParseConfig()` +- [x] Disable / Enable Extension +- [x] Update user proxies before connecting `github.com/hiddify/hiddify-core/extension.BeforeAppConnect()` +- [x] Parse Any type of configs/url `github.com/hiddify/hiddify-core/extension/sdk.ParseConfig()` - [ ] ToDo: Add Support for MultiLanguage Interface - [ ] ToDo: Custom Extension Outbound -- [ ] ToDo: Custom Extension Inbound - [ ] ToDo: Custom Extension ProxyConfig - - Demo Screenshots from HTML: - - image - image +Demo Screenshots from HTML: + +![image](https://github.com/user-attachments/assets/0fbef76f-896f-4c45-a6b8-7a2687c47013) +![image](https://github.com/user-attachments/assets/15bccfa0-d03e-4354-9368-241836d82948) + +## SingBox + +Hiddify-core به صورت پیش‌فرض بر پایه `sing-box` نسخه `v1.13.0-alpha.20` (مطابق `go.mod`) اجرا می‌شود و از ساختار رسمی معرفی‌شده در [مستندات sing-box](https://sing-box.sagernet.org/configuration/) پیروی می‌کند. + +### مفاهیم پایه + +- **ساختار پیکربندی** + + ```jsonc + { + "log": {}, + "dns": {}, + "ntp": {}, + "certificate": {}, + "endpoints": [], + "inbounds": [], + "outbounds": [], + "route": {}, + "services": [], + "experimental": {} + } + ``` + + این اسکلت با سند `index.md` در مستندات رسمی هم‌راستاست و توسط توابع `config.BuildConfig()` و `config.BuildConfigJson()` ایجاد و تکمیل می‌شود. +- **راستی‌آزمایی و قالب‌بندی** + + - اجرای `sing-box check` برای اعتبارسنجی نهایی. + - اجرای `sing-box format -w -c config.json` جهت یکسان‌سازی قالب. + - در صورت نیاز به ادغام چند فایل: `sing-box merge output.json -c config.json`. + +- **منابع رسمی برای فیلدها** + + - ورودی‌ها (Inbound): [Inbound](https://sing-box.sagernet.org/configuration/inbound/) + - خروجی‌ها (Outbound): [Outbound](https://sing-box.sagernet.org/configuration/outbound/) + - مسیریابی (Route): [Route](https://sing-box.sagernet.org/configuration/route/) + +### گردش کار در هسته + +- **تجمیع گزینه‌ها**: ساختار `config.HiddifyOptions` تنظیمات برنامه را نگهداری می‌کند و با `option.Options` کتابخانه sing-box ادغام می‌شود. +- **تولید خودکار کانفیگ**: + - تابع `config.BuildConfig()` ماژول‌های DNS، Inbound، Outbound، و Rules را با آخرین استانداردهای sing-box تنظیم می‌کند. + - تابع `config.ParseConfigContent()` ورودی‌های Clash، V2Ray یا JSON را به ساختار sing-box تبدیل و با `libbox.CheckConfig` اعتبارسنجی می‌کند. +- **به‌روزرسانی Warp و گزینه‌های پویا**: ماژول‌های `config/warp.go` و `config/outbound.go` پروفایل‌های WireGuard/WARP را مطابق API‌های sing-box 1.13 نگاشت می‌کنند. + +### نکات نسخه‌ای و مهاجرت + +- **توجه به تغییرات 1.11 تا 1.13**: قوانین DNS و Route در نسخه‌های اخیر به Rule-Setها منتقل شده‌اند. برای مهاجرت کانفیگ‌های قدیمی از راهنمای [Migration](https://sing-box.sagernet.org/migration/) استفاده کنید. +- **فعال‌سازی ویژگی‌های جدید**: گزینه‌های `Route.AutoDetectInterface` و `Experimental.ClashAPI` در `config/config.go` مطابق توصیه‌های رسمی فعال شده‌اند. +- **پیگیری انتشارها**: به‌منظور همگام‌سازی با تغییرات آینده، به مخزن [SagerNet/sing-box](https://github.com/SagerNet/sing-box) و صفحه انتشار نسخه‌ها مراجعه کنید. diff --git a/bridge/bridge.go b/bridge/bridge.go index cdd96594..4ec54810 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -1,7 +1,8 @@ -// +build cgo +//go:build cgo package bridge // #include "stdint.h" +// #include "stdlib.h" // #include "include/dart_api_dl.c" // // // Go does not allow calling C function pointers directly. So we are @@ -26,6 +27,7 @@ func SendStringToPort(port int64, msg string) { var obj C.Dart_CObject obj._type = C.Dart_CObject_kString msg_obj := C.CString(msg) // go string -> char*s + defer C.free(unsafe.Pointer(msg_obj)) // union type, we do a force conversion ptr := unsafe.Pointer(&obj.value[0]) *(**C.char)(ptr) = msg_obj diff --git a/cli/bydll/clibydll.go b/cli/bydll/clibydll.go index 02c7184f..d155e87b 100644 --- a/cli/bydll/clibydll.go +++ b/cli/bydll/clibydll.go @@ -31,5 +31,6 @@ func main() { // Call the C function result := C.parseCli(C.int(len(cArgs)), (**C.char)(unsafe.Pointer(&cArgs[0]))) + defer C.free(unsafe.Pointer(result)) fmt.Println(C.GoString(result)) } diff --git a/cmd/cmd_config.go b/cmd/cmd_config.go index f34ebb3a..7ce73ae2 100644 --- a/cmd/cmd_config.go +++ b/cmd/cmd_config.go @@ -1,7 +1,10 @@ +//go:build ignore +// +build ignore + package cmd import ( - "encoding/json" + json "github.com/goccy/go-json" "fmt" "os" "path/filepath" @@ -54,118 +57,31 @@ var commandCheck = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { err := check(configPath) if err != nil { - log.Fatal(err) - } - }, } func init() { - commandBuild.Flags().StringVarP(&commandBuildOutputPath, "output", "o", "", "write result to file path instead of stdout") - addHConfigFlags(commandBuild) - - mainCommand.AddCommand(commandBuild) - mainCommand.AddCommand(generateConfig) + commandBuild.Flags().StringVarP(&commandBuildOutputPath, "output", "o", "", "write result to file path instead of stdout") + addHConfigFlags(commandBuild) + mainCommand.AddCommand(commandBuild) + mainCommand.AddCommand(generateConfig) } func build(path string, optionsPath string) error { - if workingDir != "" { - path = filepath.Join(workingDir, path) - if optionsPath != "" { - optionsPath = filepath.Join(workingDir, optionsPath) - } - os.Chdir(workingDir) - } - options, err := readConfigAt(path) - if err != nil { - return err - } - - HiddifyOptions := &defaultConfigs // config.DefaultHiddifyOptions() - if optionsPath != "" { - HiddifyOptions, err = readHiddifyOptionsAt(optionsPath) - if err != nil { - return err - } - } - config, err := config.BuildConfigJson(*HiddifyOptions, *options) - if err != nil { - return err - } - if commandBuildOutputPath != "" { - outputPath, _ := filepath.Abs(filepath.Join(workingDir, commandBuildOutputPath)) - err = os.WriteFile(outputPath, []byte(config), 0o644) - if err != nil { - return err - } - fmt.Println("result successfully written to ", outputPath) - // libbox.Setup(outputPath, workingDir, workingDir, true) - // instance, err := NewService(*patchedOptions) - } else { - os.Stdout.WriteString(config) - } - return nil -} - -func check(path string) error { - content, err := os.ReadFile(path) - if err != nil { - return err - } - return libbox.CheckConfig(string(content)) -} - -func readConfigAt(path string) (*option.Options, error) { - content, err := os.ReadFile(path) - if err != nil { - return nil, err - } - var options option.Options - err = options.UnmarshalJSON(content) - if err != nil { - return nil, err - } - return &options, nil -} - -func readConfigBytes(content []byte) (*option.Options, error) { - var options option.Options - err := options.UnmarshalJSON(content) - if err != nil { - return nil, err + if workingDir != "" { + path = filepath.Join(workingDir, path) + if optionsPath != "" { + optionsPath = filepath.Join(workingDir, optionsPath) + } + } + if options.Masque.Enable { + // ... } return &options, nil } -func readHiddifyOptionsAt(path string) (*config.HiddifyOptions, error) { - content, err := os.ReadFile(path) - if err != nil { - return nil, err - } - var options config.HiddifyOptions - err = json.Unmarshal(content, &options) - if err != nil { - return nil, err - } - if options.Warp.WireguardConfigStr != "" { - err := json.Unmarshal([]byte(options.Warp.WireguardConfigStr), &options.Warp.WireguardConfig) - if err != nil { - return nil, err - } - } - if options.Warp2.WireguardConfigStr != "" { - err := json.Unmarshal([]byte(options.Warp2.WireguardConfigStr), &options.Warp2.WireguardConfig) - if err != nil { - return nil, err - } - } - - return &options, nil -} - func addHConfigFlags(commandRun *cobra.Command) { commandRun.Flags().StringVarP(&configPath, "config", "c", "", "proxy config path or url") commandRun.MarkFlagRequired("config") - commandRun.Flags().StringVarP(&hiddifySettingPath, "hiddify", "d", "", "Hiddify Setting JSON Path") commandRun.Flags().BoolVar(&defaultConfigs.EnableFullConfig, "full-config", false, "allows including tags other than output") commandRun.Flags().StringVar(&defaultConfigs.LogLevel, "log", "warn", "log level") commandRun.Flags().BoolVar(&defaultConfigs.InboundOptions.EnableTun, "tun", false, "Enable Tun") diff --git a/cmd/cmd_config_v113.go b/cmd/cmd_config_v113.go new file mode 100644 index 00000000..1f46fa02 --- /dev/null +++ b/cmd/cmd_config_v113.go @@ -0,0 +1,164 @@ +package cmd + +import ( + json "github.com/goccy/go-json" + "fmt" + "os" + "path/filepath" + + "github.com/hiddify/hiddify-core/config" + pb "github.com/hiddify/hiddify-core/hiddifyrpc" + v2 "github.com/hiddify/hiddify-core/v2" + "github.com/sagernet/sing-box/experimental/libbox" + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing-box/option" + + "github.com/spf13/cobra" +) + +var ( + hiddifySettingPath string + configPath string + defaultConfigs config.HiddifyOptions = *config.DefaultHiddifyOptions() + commandBuildOutputPath string +) + +var commandBuild = &cobra.Command{ + Use: "build", + Short: "Build configuration", + Run: func(cmd *cobra.Command, args []string) { + err := build(configPath, hiddifySettingPath) + if err != nil { + log.Fatal(err) + } + }, +} + +var generateConfig = &cobra.Command{ + Use: "gen", + Short: "gen configuration", + Run: func(cmd *cobra.Command, args []string) { + conf, err := v2.GenerateConfig(&pb.GenerateConfigRequest{Path: args[0]}) + if err != nil { + log.Fatal(err) + } + log.Debug(string(conf.ConfigContent)) + }, +} + +var commandCheck = &cobra.Command{ + Use: "check", + Short: "Check configuration", + Run: func(cmd *cobra.Command, args []string) { + err := check(configPath) + if err != nil { + log.Fatal(err) + } + }, +} + +func init() { + commandBuild.Flags().StringVarP(&commandBuildOutputPath, "output", "o", "", "write result to file path instead of stdout") + addHConfigFlags(commandBuild) + mainCommand.AddCommand(commandBuild) + mainCommand.AddCommand(generateConfig) + mainCommand.AddCommand(commandCheck) +} + +func build(path string, optionsPath string) error { + if workingDir != "" { + path = filepath.Join(workingDir, path) + if optionsPath != "" { + optionsPath = filepath.Join(workingDir, optionsPath) + } + os.Chdir(workingDir) + } + options, err := readConfigAt(path) + if err != nil { + return err + } + HiddifyOptions := &defaultConfigs + if optionsPath != "" { + HiddifyOptions, err = readHiddifyOptionsAt(optionsPath) + if err != nil { + return err + } + } + configStr, err := config.BuildConfigJson(*HiddifyOptions, *options) + if err != nil { + return err + } + if commandBuildOutputPath != "" { + outputPath, _ := filepath.Abs(filepath.Join(workingDir, commandBuildOutputPath)) + if err := os.WriteFile(outputPath, []byte(configStr), 0o644); err != nil { + return err + } + fmt.Println("result successfully written to ", outputPath) + } else { + os.Stdout.WriteString(configStr) + } + return nil +} + +func check(path string) error { + content, err := os.ReadFile(path) + if err != nil { + return err + } + return libbox.CheckConfig(string(content)) +} + +func readConfigAt(path string) (*option.Options, error) { + content, err := os.ReadFile(path) + if err != nil { + return nil, err + } + var options option.Options + if err := json.Unmarshal(content, &options); err != nil { + return nil, err + } + return &options, nil +} + +func readHiddifyOptionsAt(path string) (*config.HiddifyOptions, error) { + content, err := os.ReadFile(path) + if err != nil { + return nil, err + } + var options config.HiddifyOptions + if err := json.Unmarshal(content, &options); err != nil { + return nil, err + } + // if options.Warp.WireguardConfigStr != "" { + // if err := json.Unmarshal([]byte(options.Warp.WireguardConfigStr), &options.Warp.WireguardConfig); err != nil { + // return nil, err + // } + // } + // if options.Warp2.WireguardConfigStr != "" { + // if err := json.Unmarshal([]byte(options.Warp2.WireguardConfigStr), &options.Warp2.WireguardConfig); err != nil { + // return nil, err + // } + // } + return &options, nil +} + +func addHConfigFlags(commandRun *cobra.Command) { + commandRun.Flags().StringVarP(&configPath, "config", "c", "", "proxy config path or url") + commandRun.MarkFlagRequired("config") + commandRun.Flags().BoolVar(&defaultConfigs.EnableFullConfig, "full-config", false, "allows including tags other than output") + commandRun.Flags().StringVar(&defaultConfigs.LogLevel, "log", "warn", "log level") + commandRun.Flags().BoolVar(&defaultConfigs.InboundOptions.EnableTun, "tun", false, "Enable Tun") + commandRun.Flags().BoolVar(&defaultConfigs.InboundOptions.EnableTunService, "tun-service", false, "Enable Tun Service") + commandRun.Flags().BoolVar(&defaultConfigs.InboundOptions.SetSystemProxy, "system-proxy", false, "Enable System Proxy") + commandRun.Flags().Uint16Var(&defaultConfigs.InboundOptions.MixedPort, "in-proxy-port", 2334, "Input Mixed Port") + commandRun.Flags().BoolVar(&defaultConfigs.TLSTricks.EnableFragment, "fragment", false, "Enable Fragment") + commandRun.Flags().StringVar(&defaultConfigs.TLSTricks.FragmentSize, "fragment-size", "2-4", "FragmentSize") + commandRun.Flags().StringVar(&defaultConfigs.TLSTricks.FragmentSleep, "fragment-sleep", "2-4", "FragmentSleep") + commandRun.Flags().BoolVar(&defaultConfigs.TLSTricks.EnablePadding, "padding", false, "Enable Padding") + commandRun.Flags().StringVar(&defaultConfigs.TLSTricks.PaddingSize, "padding-size", "1300-1400", "PaddingSize") + commandRun.Flags().BoolVar(&defaultConfigs.TLSTricks.MixedSNICase, "mixed-sni-case", false, "MixedSNICase") + commandRun.Flags().StringVar(&defaultConfigs.RemoteDnsAddress, "dns-remote", "1.1.1.1", "RemoteDNS (1.1.1.1, https://1.1.1.1/dns-query)") + commandRun.Flags().StringVar(&defaultConfigs.DirectDnsAddress, "dns-direct", "1.1.1.1", "DirectDNS (1.1.1.1, https://1.1.1.1/dns-query)") + commandRun.Flags().StringVar(&defaultConfigs.ClashApiSecret, "web-secret", "", "Web Server Secret") + commandRun.Flags().Uint16Var(&defaultConfigs.ClashApiPort, "web-port", 6756, "Web Server Port") +} diff --git a/cmd/cmd_warp.go b/cmd/cmd_warp.go deleted file mode 100644 index df10be3e..00000000 --- a/cmd/cmd_warp.go +++ /dev/null @@ -1,126 +0,0 @@ -package cmd - -import ( - "bufio" - "encoding/json" - "fmt" - - "os" - "strings" - - "github.com/hiddify/hiddify-core/config" - T "github.com/sagernet/sing-box/option" - "github.com/spf13/cobra" -) - -var warpKey string - -var commandWarp = &cobra.Command{ - Use: "warp", - Short: "warp configuration", - Args: cobra.ExactArgs(0), - Run: func(cmd *cobra.Command, args []string) { - out, err := generateWarp() - fmt.Printf("out=%v Error! %v", out, err) - if err != nil { - fmt.Printf("Error! %v", err) - } - }, -} - -func init() { - // commandWarp.Flags().StringVarP(&warpKey, "key", "k", "", "warp key") - mainCommand.AddCommand(commandWarp) -} - -type WireGuardConfig struct { - Interface InterfaceConfig `json:"Interface"` - Peer PeerConfig `json:"Peer"` -} - -type InterfaceConfig struct { - PrivateKey string `json:"PrivateKey"` - DNS string `json:"DNS"` - Address []string `json:"Address"` -} - -type PeerConfig struct { - PublicKey string `json:"PublicKey"` - AllowedIPs []string `json:"AllowedIPs"` - Endpoint string `json:"Endpoint"` -} - -type SingboxConfig struct { - Type string `json:"type"` - Tag string `json:"tag"` - Server string `json:"server"` - ServerPort int `json:"server_port"` - LocalAddress []string `json:"local_address"` - PrivateKey string `json:"private_key"` - PeerPublicKey string `json:"peer_public_key"` - Reserved []int `json:"reserved"` - MTU int `json:"mtu"` -} - -func readWireGuardConfig(filePath string) (WireGuardConfig, error) { - file, err := os.Open(filePath) - if err != nil { - return WireGuardConfig{}, err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - - var wgConfig WireGuardConfig - var currentSection string - - for scanner.Scan() { - line := scanner.Text() - - if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { - currentSection = strings.TrimSpace(line[1 : len(line)-1]) - continue - } - - if currentSection == "Interface" { - parseInterfaceConfig(&wgConfig.Interface, line) - } else if currentSection == "Peer" { - parsePeerConfig(&wgConfig.Peer, line) - } - } - - return wgConfig, nil -} - -func parseInterfaceConfig(interfaceConfig *InterfaceConfig, line string) { - if strings.HasPrefix(line, "PrivateKey") { - interfaceConfig.PrivateKey = strings.TrimSpace(strings.SplitN(line, "=", 2)[1]) - } else if strings.HasPrefix(line, "DNS") { - interfaceConfig.DNS = strings.TrimSpace(strings.SplitN(line, "=", 2)[1]) - } else if strings.HasPrefix(line, "Address") { - interfaceConfig.Address = append(interfaceConfig.Address, strings.TrimSpace(strings.SplitN(line, "=", 2)[1])) - } -} - -func parsePeerConfig(peerConfig *PeerConfig, line string) { - if strings.HasPrefix(line, "PublicKey") { - peerConfig.PublicKey = strings.TrimSpace(strings.SplitN(line, "=", 2)[1]) - } else if strings.HasPrefix(line, "AllowedIPs") { - peerConfig.AllowedIPs = append(peerConfig.AllowedIPs, strings.TrimSpace(strings.SplitN(line, "=", 2)[1])) - } else if strings.HasPrefix(line, "Endpoint") { - peerConfig.Endpoint = strings.TrimSpace(strings.SplitN(line, "=", 2)[1]) - } -} -func generateWarp() (*T.Outbound, error) { - _, _, wg, err := config.GenerateWarpInfo("", "", "") - - // fmt.Printf("%v", wgConfig) - singboxConfig, err := config.GenerateWarpSingbox(*wg, "", 0, "", "", "", "") - singboxJSON, err := json.MarshalIndent(singboxConfig, "", " ") - if err != nil { - fmt.Println("Error marshaling Singbox configuration:", err) - return nil, err - } - fmt.Println(string(singboxJSON)) - return nil, nil -} diff --git a/config/config.go b/config/config.go index 383b1194..c2cecf75 100644 --- a/config/config.go +++ b/config/config.go @@ -3,7 +3,7 @@ package config import ( "bytes" "encoding/base64" - "encoding/json" + json "github.com/goccy/go-json" "fmt" "math/rand" "net" @@ -16,6 +16,7 @@ import ( C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" dns "github.com/sagernet/sing-dns" + badoption "github.com/sagernet/sing/common/json/badoption" ) const ( @@ -92,27 +93,6 @@ func addForceDirect(options *option.Options, opt *HiddifyOptions, directDNSDomai directDNSDomains[parsedUrl.Host] = true } if len(directDNSDomains) > 0 { - // trickDnsDomains := []string{} - // directDNSDomains = removeDuplicateStr(directDNSDomains) - // b, _ := batch.New(context.Background(), batch.WithConcurrencyNum[bool](10)) - // for _, d := range directDNSDomains { - // b.Go(d, func() (bool, error) { - // return isBlockedDomain(d), nil - // }) - // } - // b.Wait() - // for domain, isBlock := range b.Result() { - // if isBlock.Value { - // trickDnsDomains = append(trickDnsDomains, domain) - // } - // } - - // trickDomains := strings.Join(trickDnsDomains, ",") - // trickRule := Rule{Domains: trickDomains, Outbound: OutboundBypassTag} - // trickDnsRule := trickRule.MakeDNSRule() - // trickDnsRule.Server = DNSTricksDirectTag - // options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: trickDnsRule}}, options.DNS.Rules...) - directDNSDomainskeys := make([]string, 0, len(directDNSDomains)) for key := range directDNSDomains { directDNSDomainskeys = append(directDNSDomainskeys, key) @@ -121,7 +101,8 @@ func addForceDirect(options *option.Options, opt *HiddifyOptions, directDNSDomai domains := strings.Join(directDNSDomainskeys, ",") directRule := Rule{Domains: domains, Outbound: OutboundBypassTag} dnsRule := directRule.MakeDNSRule() - dnsRule.Server = DNSDirectTag + dnsRule.DNSRuleAction.Action = C.RuleActionTypeRoute + dnsRule.DNSRuleAction.RouteOptions = option.DNSRouteActionOptions{Server: DNSDirectTag} options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: dnsRule}}, options.DNS.Rules...) } } @@ -133,41 +114,18 @@ func setOutbounds(options *option.Options, input *option.Options, opt *HiddifyOp OutboundMainProxyTag = OutboundSelectTag // inbound==warp over proxies // outbound==proxies over warp - if opt.Warp.EnableWarp { - for _, out := range input.Outbounds { - if out.Type == C.TypeCustom { - if warp, ok := out.CustomOptions["warp"].(map[string]interface{}); ok { - key, _ := warp["key"].(string) - if key == "p1" { - opt.Warp.EnableWarp = false - break - } - } - } - if out.Type == C.TypeWireGuard && (out.WireGuardOptions.PrivateKey == opt.Warp.WireguardConfig.PrivateKey || out.WireGuardOptions.PrivateKey == "p1") { - opt.Warp.EnableWarp = false - break - } - } - } - if opt.Warp.EnableWarp && (opt.Warp.Mode == "warp_over_proxy" || opt.Warp.Mode == "proxy_over_warp") { - out, err := GenerateWarpSingbox(opt.Warp.WireguardConfig, opt.Warp.CleanIP, opt.Warp.CleanPort, opt.Warp.FakePackets, opt.Warp.FakePacketSize, opt.Warp.FakePacketDelay, opt.Warp.FakePacketMode) - if err != nil { - return fmt.Errorf("failed to generate warp config: %v", err) - } - out.Tag = "Hiddify Warp ✅" - if opt.Warp.Mode == "warp_over_proxy" { - out.WireGuardOptions.Detour = OutboundSelectTag - OutboundMainProxyTag = out.Tag - } else { - out.WireGuardOptions.Detour = OutboundDirectTag - } - patchWarp(out, opt, true, nil) - outbounds = append(outbounds, *out) - // tags = append(tags, out.Tag) + // Note: WARP detour wiring and fragmentation will be adapted later for v1.13 API + if opt.Masque.Enable { + // out, err := GenerateWarpSingbox(opt.Warp.WireguardConfig, opt.Warp.CleanIP, opt.Warp.CleanPort, opt.Warp.FakePackets, opt.Warp.FakePacketSize, opt.Warp.FakePacketDelay, opt.Warp.FakePacketMode) + // if err != nil { + // return fmt.Errorf("failed to generate warp config: %v", err) + // } + // out.Tag = "Hiddify Warp " + // OutboundMainProxyTag = out.Tag + // outbounds = append(outbounds, *out) } for _, out := range input.Outbounds { - outbound, serverDomain, err := patchOutbound(out, *opt, options.DNS.StaticIPs) + outbound, serverDomain, err := patchOutbound(out, *opt, nil) if err != nil { return err } @@ -182,29 +140,18 @@ func setOutbounds(options *option.Options, input *option.Options, opt *HiddifyOp continue case C.TypeSelector, C.TypeURLTest: continue - case C.TypeCustom: - continue default: if !strings.Contains(out.Tag, "§hide§") { tags = append(tags, out.Tag) } - out = patchHiddifyWarpFromConfig(out, *opt) outbounds = append(outbounds, out) } } urlTest := option.Outbound{ - Type: C.TypeURLTest, - Tag: OutboundURLTestTag, - URLTestOptions: option.URLTestOutboundOptions{ - Outbounds: tags, - URL: opt.ConnectionTestUrl, - Interval: option.Duration(opt.URLTestInterval.Duration()), - // IdleTimeout: option.Duration(opt.URLTestIdleTimeout.Duration()), - Tolerance: 1, - IdleTimeout: option.Duration(opt.URLTestInterval.Duration().Nanoseconds() * 3), - InterruptExistConnections: true, - }, + Type: C.TypeURLTest, + Tag: OutboundURLTestTag, + Options: option.URLTestOutboundOptions{Outbounds: tags, URL: opt.ConnectionTestUrl, Interval: badoption.Duration(opt.URLTestInterval.Duration()), Tolerance: 1, IdleTimeout: badoption.Duration(opt.URLTestInterval.Duration().Nanoseconds() * 3), InterruptExistConnections: true}, } defaultSelect := urlTest.Tag @@ -213,15 +160,7 @@ func setOutbounds(options *option.Options, input *option.Options, opt *HiddifyOp defaultSelect = "§default§" } } - selector := option.Outbound{ - Type: C.TypeSelector, - Tag: OutboundSelectTag, - SelectorOptions: option.SelectorOutboundOptions{ - Outbounds: append([]string{urlTest.Tag}, tags...), - Default: defaultSelect, - InterruptExistConnections: true, - }, - } + selector := option.Outbound{Type: C.TypeSelector, Tag: OutboundSelectTag, Options: option.SelectorOutboundOptions{Outbounds: append([]string{urlTest.Tag}, tags...), Default: defaultSelect, InterruptExistConnections: true}} outbounds = append([]option.Outbound{selector, urlTest}, outbounds...) @@ -239,14 +178,9 @@ func setOutbounds(options *option.Options, input *option.Options, opt *HiddifyOp { Tag: OutboundDirectFragmentTag, Type: C.TypeDirect, - DirectOptions: option.DirectOutboundOptions{ + Options: option.DirectOutboundOptions{ DialerOptions: option.DialerOptions{ TCPFastOpen: false, - TLSFragment: option.TLSFragmentOptions{ - Enabled: true, - Size: opt.TLSTricks.FragmentSize, - Sleep: opt.TLSTricks.FragmentSleep, - }, }, }, }, @@ -272,7 +206,7 @@ func setClashAPI(options *option.Options, opt *HiddifyOptions) { } options.Experimental = &option.ExperimentalOptions{ ClashAPI: &option.ClashAPIOptions{ - ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", opt.ClashApiPort), + ExternalController: fmt.Sprintf("%s:%d", opt.ClashApiHost, opt.ClashApiPort), Secret: opt.ClashApiSecret, }, @@ -285,537 +219,478 @@ func setClashAPI(options *option.Options, opt *HiddifyOptions) { } func setLog(options *option.Options, opt *HiddifyOptions) { - options.Log = &option.LogOptions{ - Level: opt.LogLevel, - Output: opt.LogFile, - Disabled: false, - Timestamp: true, - DisableColor: true, - } + options.Log = &option.LogOptions{ + Level: opt.LogLevel, + Output: opt.LogFile, + Disabled: false, + Timestamp: true, + DisableColor: true, + } } func setInbound(options *option.Options, opt *HiddifyOptions) { - var inboundDomainStrategy option.DomainStrategy - if !opt.ResolveDestination { - inboundDomainStrategy = option.DomainStrategy(dns.DomainStrategyAsIS) - } else { - inboundDomainStrategy = opt.IPv6Mode - } - if opt.EnableTunService { - ActivateTunnelService(*opt) - } else if opt.EnableTun { - tunInbound := option.Inbound{ - Type: C.TypeTun, - Tag: InboundTUNTag, - - TunOptions: option.TunInboundOptions{ - Stack: opt.TUNStack, - MTU: opt.MTU, - AutoRoute: true, - StrictRoute: opt.StrictRoute, - EndpointIndependentNat: true, - // GSO: runtime.GOOS != "windows", - InboundOptions: option.InboundOptions{ - SniffEnabled: true, - SniffOverrideDestination: false, - DomainStrategy: inboundDomainStrategy, - }, - }, - } - switch opt.IPv6Mode { - case option.DomainStrategy(dns.DomainStrategyUseIPv4): - tunInbound.TunOptions.Inet4Address = []netip.Prefix{ - netip.MustParsePrefix("172.19.0.1/28"), - } - case option.DomainStrategy(dns.DomainStrategyUseIPv6): - tunInbound.TunOptions.Inet6Address = []netip.Prefix{ - netip.MustParsePrefix("fdfe:dcba:9876::1/126"), - } - default: - tunInbound.TunOptions.Inet4Address = []netip.Prefix{ - netip.MustParsePrefix("172.19.0.1/28"), - } - tunInbound.TunOptions.Inet6Address = []netip.Prefix{ - netip.MustParsePrefix("fdfe:dcba:9876::1/126"), - } - } - options.Inbounds = append(options.Inbounds, tunInbound) - - } - - var bind string - if opt.AllowConnectionFromLAN { - bind = "0.0.0.0" - } else { - bind = "127.0.0.1" - } - - options.Inbounds = append( - options.Inbounds, - option.Inbound{ - Type: C.TypeMixed, - Tag: InboundMixedTag, - MixedOptions: option.HTTPMixedInboundOptions{ - ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.MustParseAddr(bind)), - ListenPort: opt.MixedPort, - InboundOptions: option.InboundOptions{ - SniffEnabled: true, - SniffOverrideDestination: true, - DomainStrategy: inboundDomainStrategy, - }, - }, - SetSystemProxy: opt.SetSystemProxy, - }, - }, - ) - - options.Inbounds = append( - options.Inbounds, - option.Inbound{ - Type: C.TypeDirect, - Tag: InboundDNSTag, - DirectOptions: option.DirectInboundOptions{ - ListenOptions: option.ListenOptions{ - Listen: option.NewListenAddress(netip.MustParseAddr(bind)), - ListenPort: opt.LocalDnsPort, - }, - // OverrideAddress: "1.1.1.1", - // OverridePort: 53, - }, - }, - ) + var inboundDomainStrategy option.DomainStrategy + if !opt.ResolveDestination { + inboundDomainStrategy = option.DomainStrategy(dns.DomainStrategyAsIS) + } else { + inboundDomainStrategy = opt.IPv6Mode + } + if opt.EnableTunService { + ActivateTunnelService(*opt) + } else if opt.EnableTun { + tunOpt := option.TunInboundOptions{ + Stack: opt.TUNStack, + MTU: opt.MTU, + AutoRoute: true, + StrictRoute: opt.StrictRoute, + InboundOptions: option.InboundOptions{ + SniffEnabled: true, + SniffOverrideDestination: false, + DomainStrategy: inboundDomainStrategy, + }, + } + options.Inbounds = append(options.Inbounds, option.Inbound{Type: C.TypeTun, Tag: InboundTUNTag, Options: tunOpt}) + } + + var bind string + if opt.AllowConnectionFromLAN { + bind = "0.0.0.0" + } else { + bind = "127.0.0.1" + } + + mixedListenAddr := badoption.Addr(netip.MustParseAddr(bind)) + options.Inbounds = append(options.Inbounds, option.Inbound{ + Type: C.TypeMixed, + Tag: InboundMixedTag, + Options: option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: &mixedListenAddr, + ListenPort: opt.MixedPort, + InboundOptions: option.InboundOptions{ + SniffEnabled: true, + SniffOverrideDestination: true, + DomainStrategy: inboundDomainStrategy, + }, + }, + SetSystemProxy: opt.SetSystemProxy, + }, + }) + + dnsListenAddr := badoption.Addr(netip.MustParseAddr(bind)) + options.Inbounds = append(options.Inbounds, option.Inbound{ + Type: C.TypeDirect, + Tag: InboundDNSTag, + Options: option.DirectInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: &dnsListenAddr, + ListenPort: opt.LocalDnsPort, + }, + }, + }) } func setDns(options *option.Options, opt *HiddifyOptions) { - options.DNS = &option.DNSOptions{ - StaticIPs: map[string][]string{}, - DNSClientOptions: option.DNSClientOptions{ - IndependentCache: opt.IndependentDNSCache, - }, - Final: DNSRemoteTag, - Servers: []option.DNSServerOptions{ - { - Tag: DNSRemoteTag, - Address: opt.RemoteDnsAddress, - AddressResolver: DNSDirectTag, - Strategy: opt.RemoteDnsDomainStrategy, - }, - { - Tag: DNSTricksDirectTag, - Address: "https://sky.rethinkdns.com/", - // AddressResolver: "dns-local", - Strategy: opt.DirectDnsDomainStrategy, - Detour: OutboundDirectFragmentTag, - }, - { - Tag: DNSDirectTag, - Address: opt.DirectDnsAddress, - AddressResolver: DNSLocalTag, - Strategy: opt.DirectDnsDomainStrategy, - Detour: OutboundDirectTag, - }, - { - Tag: DNSLocalTag, - Address: "local", - Detour: OutboundDirectTag, - }, - { - Tag: DNSBlockTag, - Address: "rcode://success", - }, - }, - } - sky_rethinkdns := getIPs([]string{"www.speedtest.net", "sky.rethinkdns.com"}) - if len(sky_rethinkdns) > 0 { - options.DNS.StaticIPs["sky.rethinkdns.com"] = sky_rethinkdns - } + options.DNS = &option.DNSOptions{ + RawDNSOptions: option.RawDNSOptions{ + DNSClientOptions: option.DNSClientOptions{ + IndependentCache: opt.IndependentDNSCache, + }, + Final: DNSRemoteTag, + Servers: []option.DNSServerOptions{ + {Tag: DNSRemoteTag, Options: option.LegacyDNSServerOptions{Address: opt.RemoteDnsAddress, AddressResolver: DNSDirectTag, Strategy: opt.RemoteDnsDomainStrategy}}, + {Tag: DNSTricksDirectTag, Options: option.LegacyDNSServerOptions{Address: "https://sky.rethinkdns.com/", Strategy: opt.DirectDnsDomainStrategy, Detour: OutboundDirectTag}}, + {Tag: DNSDirectTag, Options: option.LegacyDNSServerOptions{Address: opt.DirectDnsAddress, AddressResolver: DNSLocalTag, Strategy: opt.DirectDnsDomainStrategy, Detour: OutboundDirectTag}}, + {Tag: DNSLocalTag, Type: C.DNSTypeLocal, Options: option.LocalDNSServerOptions{}}, + {Tag: DNSBlockTag, Options: option.LegacyDNSServerOptions{Address: "rcode://success"}}, + }, + }, + } } func setFakeDns(options *option.Options, opt *HiddifyOptions) { - if opt.EnableFakeDNS { - inet4Range := netip.MustParsePrefix("198.18.0.0/15") - inet6Range := netip.MustParsePrefix("fc00::/18") - options.DNS.FakeIP = &option.DNSFakeIPOptions{ - Enabled: true, - Inet4Range: &inet4Range, - Inet6Range: &inet6Range, - } - options.DNS.Servers = append( - options.DNS.Servers, - option.DNSServerOptions{ - Tag: DNSFakeTag, - Address: "fakeip", - Strategy: option.DomainStrategy(dns.DomainStrategyUseIPv4), - }, - ) - options.DNS.Rules = append( - options.DNS.Rules, - option.DNSRule{ - Type: C.RuleTypeDefault, - DefaultOptions: option.DefaultDNSRule{ - Inbound: []string{InboundTUNTag}, - Server: DNSFakeTag, - DisableCache: true, - }, - }, - ) - - } + if opt.EnableFakeDNS { + inet4Range := netip.MustParsePrefix("198.18.0.0/15") + inet6Range := netip.MustParsePrefix("fc00::/18") + inet4Prefix := badoption.Prefix(inet4Range) + inet6Prefix := badoption.Prefix(inet6Range) + options.DNS.Servers = append(options.DNS.Servers, option.DNSServerOptions{ + Tag: DNSFakeTag, + Type: C.DNSTypeFakeIP, + Options: option.FakeIPDNSServerOptions{ + Inet4Range: &inet4Prefix, + Inet6Range: &inet6Prefix, + }, + }) + options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultDNSRule{ + RawDefaultDNSRule: option.RawDefaultDNSRule{ + Inbound: badoption.Listable[string]{InboundTUNTag}, + }, + DNSRuleAction: option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSFakeTag, DisableCache: true}}, + }, + }) + } } func setRoutingOptions(options *option.Options, opt *HiddifyOptions) { - dnsRules := []option.DefaultDNSRule{} - routeRules := []option.Rule{} - rulesets := []option.RuleSet{} - - if opt.EnableTun && runtime.GOOS == "android" { - routeRules = append( - routeRules, - option.Rule{ - Type: C.RuleTypeDefault, - - DefaultOptions: option.DefaultRule{ - Inbound: []string{InboundTUNTag}, - PackageName: []string{"app.hiddify.com"}, - Outbound: OutboundBypassTag, - }, - }, - ) - // routeRules = append( - // routeRules, - // option.Rule{ - // Type: C.RuleTypeDefault, - // DefaultOptions: option.DefaultRule{ - // ProcessName: []string{"Hiddify", "Hiddify.exe", "HiddifyCli", "HiddifyCli.exe"}, - // Outbound: OutboundBypassTag, - // }, - // }, - // ) - } - routeRules = append(routeRules, option.Rule{ - Type: C.RuleTypeDefault, - DefaultOptions: option.DefaultRule{ - Inbound: []string{InboundDNSTag}, - Outbound: OutboundDNSTag, - }, - }) - routeRules = append(routeRules, option.Rule{ - Type: C.RuleTypeDefault, - DefaultOptions: option.DefaultRule{ - Port: []uint16{53}, - Outbound: OutboundDNSTag, - }, - }) - - // { - // Type: C.RuleTypeDefault, - // DefaultOptions: option.DefaultRule{ - // ClashMode: "Direct", - // Outbound: OutboundDirectTag, - // }, - // }, - // { - // Type: C.RuleTypeDefault, - // DefaultOptions: option.DefaultRule{ - // ClashMode: "Global", - // Outbound: OutboundMainProxyTag, - // }, - // }, } - - if opt.BypassLAN { - routeRules = append( - routeRules, - option.Rule{ - Type: C.RuleTypeDefault, - DefaultOptions: option.DefaultRule{ - // GeoIP: []string{"private"}, - IPIsPrivate: true, - Outbound: OutboundBypassTag, - }, - }, - ) - } - - for _, rule := range opt.Rules { - routeRule := rule.MakeRule() - switch rule.Outbound { - case "bypass": - routeRule.Outbound = OutboundBypassTag - case "block": - routeRule.Outbound = OutboundBlockTag - case "proxy": - routeRule.Outbound = OutboundMainProxyTag - } - - if routeRule.IsValid() { - routeRules = append( - routeRules, - option.Rule{ - Type: C.RuleTypeDefault, - DefaultOptions: routeRule, - }, - ) - } - - dnsRule := rule.MakeDNSRule() - switch rule.Outbound { - case "bypass": - dnsRule.Server = DNSDirectTag - case "block": - dnsRule.Server = DNSBlockTag - dnsRule.DisableCache = true - case "proxy": - if opt.EnableFakeDNS { - fakeDnsRule := dnsRule - fakeDnsRule.Server = DNSFakeTag - fakeDnsRule.Inbound = []string{InboundTUNTag, InboundMixedTag} - dnsRules = append(dnsRules, fakeDnsRule) - } - dnsRule.Server = DNSRemoteTag - } - dnsRules = append(dnsRules, dnsRule) - } - - parsedURL, err := url.Parse(opt.ConnectionTestUrl) - if err == nil { - var dnsCPttl uint32 = 3000 - dnsRules = append(dnsRules, option.DefaultDNSRule{ - Domain: []string{parsedURL.Host}, - Server: DNSRemoteTag, - RewriteTTL: &dnsCPttl, - DisableCache: false, - }) - } - - if opt.BlockAds { - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geosite-ads", - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-category-ads-all.srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geosite-malware", - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-malware.srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geosite-phishing", - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-phishing.srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geosite-cryptominers", - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-cryptominers.srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geoip-phishing", - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geoip-phishing.srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geoip-malware", - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geoip-malware.srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - - routeRules = append(routeRules, option.Rule{ - Type: C.RuleTypeDefault, - DefaultOptions: option.DefaultRule{ - RuleSet: []string{ - "geosite-ads", - "geosite-malware", - "geosite-phishing", - "geosite-cryptominers", - "geoip-malware", - "geoip-phishing", - }, - Outbound: OutboundBlockTag, - }, - }) - dnsRules = append(dnsRules, option.DefaultDNSRule{ - RuleSet: []string{ - "geosite-ads", - "geosite-malware", - "geosite-phishing", - "geosite-cryptominers", - "geoip-malware", - "geoip-phishing", - }, - Server: DNSBlockTag, - // DisableCache: true, - }) - - } - if opt.Region != "other" { - dnsRules = append(dnsRules, option.DefaultDNSRule{ - DomainSuffix: []string{"." + opt.Region}, - Server: DNSDirectTag, - }) - routeRules = append(routeRules, option.Rule{ - Type: C.RuleTypeDefault, - DefaultOptions: option.DefaultRule{ - DomainSuffix: []string{"." + opt.Region}, - Outbound: OutboundDirectTag, - }, - }) - dnsRules = append(dnsRules, option.DefaultDNSRule{ - RuleSet: []string{ - "geoip-" + opt.Region, - "geosite-" + opt.Region, - }, - Server: DNSDirectTag, - }) - - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geoip-" + opt.Region, - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/country/geoip-" + opt.Region + ".srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - rulesets = append(rulesets, option.RuleSet{ - Type: C.RuleSetTypeRemote, - Tag: "geosite-" + opt.Region, - Format: C.RuleSetFormatBinary, - RemoteOptions: option.RemoteRuleSet{ - URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/country/geosite-" + opt.Region + ".srs", - UpdateInterval: option.Duration(5 * time.Hour * 24), - }, - }) - - routeRules = append(routeRules, option.Rule{ - Type: C.RuleTypeDefault, - DefaultOptions: option.DefaultRule{ - RuleSet: []string{ - "geoip-" + opt.Region, - "geosite-" + opt.Region, - }, - Outbound: OutboundDirectTag, - }, - }) - - } - options.Route = &option.RouteOptions{ - Rules: routeRules, - Final: OutboundMainProxyTag, - AutoDetectInterface: true, - OverrideAndroidVPN: true, - RuleSet: rulesets, - // GeoIP: &option.GeoIPOptions{ - // Path: opt.GeoIPPath, - // }, - // Geosite: &option.GeositeOptions{ - // Path: opt.GeoSitePath, - // }, - } - if opt.EnableDNSRouting { - for _, dnsRule := range dnsRules { - if dnsRule.IsValid() { - options.DNS.Rules = append( - options.DNS.Rules, - option.DNSRule{ - Type: C.RuleTypeDefault, - DefaultOptions: dnsRule, - }, - ) - } - } - } + dnsRules := []option.DefaultDNSRule{} + routeRules := []option.Rule{} + rulesets := []option.RuleSet{} + + if opt.EnableTun && runtime.GOOS == "android" { + routeRules = append( + routeRules, + option.Rule{ + Type: C.RuleTypeDefault, + + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: badoption.Listable[string]{InboundTUNTag}, + PackageName: badoption.Listable[string]{"app.hiddify.com"}, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundBypassTag}}, + }, + }, + ) + // routeRules = append( + // routeRules, + // option.Rule{ + // Type: C.RuleTypeDefault, + // DefaultOptions: option.DefaultRule{ + // ProcessName: []string{"Hiddify", "Hiddify.exe", "HiddifyCli", "HiddifyCli.exe"}, + // Outbound: OutboundBypassTag, + // }, + // }, + // ) + } + routeRules = append(routeRules, option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: badoption.Listable[string]{InboundDNSTag}, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundDNSTag}}, + }, + }) + routeRules = append(routeRules, option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Port: badoption.Listable[uint16]{53}, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundDNSTag}}, + }, + }) + + // { + // Type: C.RuleTypeDefault, + // DefaultOptions: option.DefaultRule{ + // ClashMode: "Direct", + // Outbound: OutboundDirectTag, + // }, + // }, + // { + // Type: C.RuleTypeDefault, + // DefaultOptions: option.DefaultRule{ + // ClashMode: "Global", + // Outbound: OutboundMainProxyTag, + // }, + // }, } + + if opt.BypassLAN { + routeRules = append( + routeRules, + option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + // GeoIP: []string{"private"}, + IPIsPrivate: true, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundBypassTag}}, + }, + }, + ) + } + + if len(opt.ExtraBypassCIDRs) > 0 { + routeRules = append(routeRules, option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + IPCIDR: badoption.Listable[string](opt.ExtraBypassCIDRs), + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundBypassTag}}, + }, + }) + } + + for _, rule := range opt.Rules { + routeRule := rule.MakeRule() + switch rule.Outbound { + case "bypass": + routeRule.RuleAction = option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundBypassTag}} + case "block": + routeRule.RuleAction = option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundBlockTag}} + case "proxy": + routeRule.RuleAction = option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundMainProxyTag}} + } + + if routeRule.IsValid() { + routeRules = append( + routeRules, + option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: routeRule, + }, + ) + } + + dnsRule := rule.MakeDNSRule() + switch rule.Outbound { + case "bypass": + dnsRule.DNSRuleAction = option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSDirectTag}} + case "block": + dnsRule.DNSRuleAction = option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSBlockTag, DisableCache: true}} + case "proxy": + if opt.EnableFakeDNS { + fakeDnsRule := dnsRule + fakeDnsRule.DNSRuleAction = option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSFakeTag}} + fakeDnsRule.RawDefaultDNSRule.Inbound = badoption.Listable[string]{InboundTUNTag, InboundMixedTag} + dnsRules = append(dnsRules, fakeDnsRule) + } + dnsRule.DNSRuleAction = option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSRemoteTag}} + } + dnsRules = append(dnsRules, dnsRule) + } + + parsedURL, err := url.Parse(opt.ConnectionTestUrl) + if err == nil { + var dnsCPttl uint32 = 3000 + dnsRules = append(dnsRules, option.DefaultDNSRule{ + RawDefaultDNSRule: option.RawDefaultDNSRule{ + Domain: badoption.Listable[string]{parsedURL.Host}, + }, + DNSRuleAction: option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSRemoteTag, RewriteTTL: &dnsCPttl}}, + }) + } + + if opt.BlockAds { + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geosite-ads", + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/block/geosite-category-ads-all.srs", opt.GeoRulesBaseURL), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geosite-malware", + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/block/geosite-malware.srs", opt.GeoRulesBaseURL), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geosite-phishing", + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/block/geosite-phishing.srs", opt.GeoRulesBaseURL), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geosite-cryptominers", + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/block/geosite-cryptominers.srs", opt.GeoRulesBaseURL), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geoip-phishing", + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/block/geoip-phishing.srs", opt.GeoRulesBaseURL), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geoip-malware", + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/block/geoip-malware.srs", opt.GeoRulesBaseURL), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + + routeRules = append(routeRules, option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + RuleSet: badoption.Listable[string]{ + "geosite-ads", + "geosite-malware", + "geosite-phishing", + "geosite-cryptominers", + "geoip-malware", + "geoip-phishing", + }, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundBlockTag}}, + }, + }) + dnsRules = append(dnsRules, option.DefaultDNSRule{ + RawDefaultDNSRule: option.RawDefaultDNSRule{ + RuleSet: badoption.Listable[string]{ + "geosite-ads", + "geosite-malware", + "geosite-phishing", + "geosite-cryptominers", + "geoip-malware", + "geoip-phishing", + }, + }, + DNSRuleAction: option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSBlockTag}}, + }) + // DisableCache: true, + } + + if opt.Region == "ir" { + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geosite-category-ads-ir", + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/block/geosite-category-ads-ir.srs", opt.GeoRulesBaseURL), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + routeRules = append(routeRules, option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + RuleSet: badoption.Listable[string]{"geosite-category-ads-ir"}, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundBlockTag}}, + }, + }) + } + + if opt.Region != "other" { + dnsRules = append(dnsRules, option.DefaultDNSRule{ + RawDefaultDNSRule: option.RawDefaultDNSRule{ + DomainSuffix: badoption.Listable[string]{"." + opt.Region}, + }, + DNSRuleAction: option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSDirectTag}}, + }) + routeRules = append(routeRules, option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + DomainSuffix: badoption.Listable[string]{"." + opt.Region}, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundDirectTag}}, + }, + }) + dnsRules = append(dnsRules, option.DefaultDNSRule{ + RawDefaultDNSRule: option.RawDefaultDNSRule{ + RuleSet: badoption.Listable[string]{ + "geoip-" + opt.Region, + "geosite-" + opt.Region, + }, + }, + DNSRuleAction: option.DNSRuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{Server: DNSDirectTag}}, + }) + + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geoip-" + opt.Region, + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/country/geoip-%s.srs", opt.GeoRulesBaseURL, opt.Region), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + rulesets = append(rulesets, option.RuleSet{ + Type: C.RuleSetTypeRemote, + Tag: "geosite-" + opt.Region, + Format: C.RuleSetFormatBinary, + RemoteOptions: option.RemoteRuleSet{ + URL: fmt.Sprintf("%s/rule-set/country/geosite-%s.srs", opt.GeoRulesBaseURL, opt.Region), + UpdateInterval: badoption.Duration(5 * time.Hour * 24), + }, + }) + + routeRules = append(routeRules, option.Rule{ + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + RuleSet: badoption.Listable[string]{ + "geoip-" + opt.Region, + "geosite-" + opt.Region, + }, + }, + RuleAction: option.RuleAction{Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{Outbound: OutboundDirectTag}}, + }, + }) + + } + options.Route = &option.RouteOptions{ + Rules: routeRules, + Final: OutboundMainProxyTag, + AutoDetectInterface: true, + OverrideAndroidVPN: true, + RuleSet: rulesets, + // GeoIP: &option.GeoIPOptions{ + // Path: opt.GeoIPPath, + // }, + // Geosite: &option.GeositeOptions{ + // Path: opt.GeoSitePath, + // }, + } + if opt.EnableDNSRouting { + for _, dnsRule := range dnsRules { + if dnsRule.IsValid() { + options.DNS.Rules = append( + options.DNS.Rules, + option.DNSRule{ + Type: C.RuleTypeDefault, + DefaultOptions: dnsRule, + }, + ) + } + } + } } func patchHiddifyWarpFromConfig(out option.Outbound, opt HiddifyOptions) option.Outbound { - if opt.Warp.EnableWarp && opt.Warp.Mode == "proxy_over_warp" { - if out.DirectOptions.Detour == "" { - out.DirectOptions.Detour = "Hiddify Warp ✅" - } - if out.HTTPOptions.Detour == "" { - out.HTTPOptions.Detour = "Hiddify Warp ✅" - } - if out.Hysteria2Options.Detour == "" { - out.Hysteria2Options.Detour = "Hiddify Warp ✅" - } - if out.HysteriaOptions.Detour == "" { - out.HysteriaOptions.Detour = "Hiddify Warp ✅" - } - if out.SSHOptions.Detour == "" { - out.SSHOptions.Detour = "Hiddify Warp ✅" - } - if out.ShadowTLSOptions.Detour == "" { - out.ShadowTLSOptions.Detour = "Hiddify Warp ✅" - } - if out.ShadowsocksOptions.Detour == "" { - out.ShadowsocksOptions.Detour = "Hiddify Warp ✅" - } - if out.ShadowsocksROptions.Detour == "" { - out.ShadowsocksROptions.Detour = "Hiddify Warp ✅" - } - if out.SocksOptions.Detour == "" { - out.SocksOptions.Detour = "Hiddify Warp ✅" - } - if out.TUICOptions.Detour == "" { - out.TUICOptions.Detour = "Hiddify Warp ✅" - } - if out.TorOptions.Detour == "" { - out.TorOptions.Detour = "Hiddify Warp ✅" - } - if out.TrojanOptions.Detour == "" { - out.TrojanOptions.Detour = "Hiddify Warp ✅" - } - if out.VLESSOptions.Detour == "" { - out.VLESSOptions.Detour = "Hiddify Warp ✅" - } - if out.VMessOptions.Detour == "" { - out.VMessOptions.Detour = "Hiddify Warp ✅" - } - if out.WireGuardOptions.Detour == "" { - out.WireGuardOptions.Detour = "Hiddify Warp ✅" - } - } - return out + return out } func getIPs(domains []string) []string { - res := []string{} - for _, d := range domains { - ips, err := net.LookupHost(d) - if err != nil { - continue - } - for _, ip := range ips { - if !strings.HasPrefix(ip, "10.") { - res = append(res, ip) - } - } - } - return res + res := []string{} + for _, d := range domains { + ips, err := net.LookupHost(d) + if err != nil { + continue + } + for _, ip := range ips { + if !strings.HasPrefix(ip, "10.") { + res = append(res, ip) + } + } + } + return res } func isBlockedDomain(domain string) bool { diff --git a/config/debug.go b/config/debug.go index fab5a9ed..78582870 100644 --- a/config/debug.go +++ b/config/debug.go @@ -1,8 +1,8 @@ package config import ( + json "github.com/goccy/go-json" "bytes" - "encoding/json" "fmt" "os" "path/filepath" diff --git a/config/hiddify_option.go b/config/hiddify_option.go index 5b13242e..cca0058f 100644 --- a/config/hiddify_option.go +++ b/config/hiddify_option.go @@ -12,16 +12,17 @@ type HiddifyOptions struct { EnableClashApi bool `json:"enable-clash-api"` ClashApiPort uint16 `json:"clash-api-port"` ClashApiSecret string `json:"web-secret"` + ClashApiHost string `json:"clash-api-host"` Region string `json:"region"` BlockAds bool `json:"block-ads"` UseXrayCoreWhenPossible bool `json:"use-xray-core-when-possible"` // GeoIPPath string `json:"geoip-path"` // GeoSitePath string `json:"geosite-path"` Rules []Rule `json:"rules"` - Warp WarpOptions `json:"warp"` - Warp2 WarpOptions `json:"warp2"` + Masque MasqueOptions `json:"masque"` Mux MuxOptions `json:"mux"` TLSTricks TLSTricks `json:"tls-tricks"` + GeoRulesBaseURL string `json:"geo-rules-base-url"` DNSOptions InboundOptions URLTestOptions @@ -39,117 +40,123 @@ type DNSOptions struct { } type InboundOptions struct { - EnableTun bool `json:"enable-tun"` - EnableTunService bool `json:"enable-tun-service"` - SetSystemProxy bool `json:"set-system-proxy"` - MixedPort uint16 `json:"mixed-port"` - TProxyPort uint16 `json:"tproxy-port"` - LocalDnsPort uint16 `json:"local-dns-port"` - MTU uint32 `json:"mtu"` - StrictRoute bool `json:"strict-route"` - TUNStack string `json:"tun-implementation"` + EnableTun bool `json:"enable-tun"` + EnableTunService bool `json:"enable-tun-service"` + SetSystemProxy bool `json:"set-system-proxy"` + MixedPort uint16 `json:"mixed-port"` + TProxyPort uint16 `json:"tproxy-port"` + LocalDnsPort uint16 `json:"local-dns-port"` + MTU uint32 `json:"mtu"` + StrictRoute bool `json:"strict-route"` + TUNStack string `json:"tun-implementation"` } type URLTestOptions struct { - ConnectionTestUrl string `json:"connection-test-url"` - URLTestInterval DurationInSeconds `json:"url-test-interval"` - // URLTestIdleTimeout DurationInSeconds `json:"url-test-idle-timeout"` + ConnectionTestUrl string `json:"connection-test-url"` + URLTestInterval DurationInSeconds `json:"url-test-interval"` + // URLTestIdleTimeout DurationInSeconds `json:"url-test-idle-timeout"` } type RouteOptions struct { - ResolveDestination bool `json:"resolve-destination"` - IPv6Mode option.DomainStrategy `json:"ipv6-mode"` - BypassLAN bool `json:"bypass-lan"` - AllowConnectionFromLAN bool `json:"allow-connection-from-lan"` + ResolveDestination bool `json:"resolve-destination"` + IPv6Mode option.DomainStrategy `json:"ipv6-mode"` + BypassLAN bool `json:"bypass-lan"` + AllowConnectionFromLAN bool `json:"allow-connection-from-lan"` + ExtraBypassCIDRs []string `json:"extra-bypass-cidrs"` } type TLSTricks struct { - EnableFragment bool `json:"enable-fragment"` - FragmentSize string `json:"fragment-size"` - FragmentSleep string `json:"fragment-sleep"` - MixedSNICase bool `json:"mixed-sni-case"` - EnablePadding bool `json:"enable-padding"` - PaddingSize string `json:"padding-size"` + EnableFragment bool `json:"enable-fragment"` + FragmentSize string `json:"fragment-size"` + FragmentSleep string `json:"fragment-sleep"` + MixedSNICase bool `json:"mixed-sni-case"` + EnablePadding bool `json:"enable-padding"` + PaddingSize string `json:"padding-size"` + EnableECH bool `json:"enable-ech"` + ECHConfig string `json:"ech-config"` + ECHConfigPath string `json:"ech-config-path"` + EnableReality bool `json:"enable-reality"` + RealityPublicKey string `json:"reality-public-key"` + RealityShortID string `json:"reality-short-id"` } type MuxOptions struct { - Enable bool `json:"enable"` - Padding bool `json:"padding"` - MaxStreams int `json:"max-streams"` - Protocol string `json:"protocol"` + Enable bool `json:"enable"` + Padding bool `json:"padding"` + MaxStreams int `json:"max-streams"` + Protocol string `json:"protocol"` } -type WarpOptions struct { - Id string `json:"id"` - EnableWarp bool `json:"enable"` - Mode string `json:"mode"` - WireguardConfigStr string `json:"wireguard-config"` - WireguardConfig WarpWireguardConfig `json:"wireguardConfig"` // TODO check - FakePackets string `json:"noise"` - FakePacketSize string `json:"noise-size"` - FakePacketDelay string `json:"noise-delay"` - FakePacketMode string `json:"noise-mode"` - CleanIP string `json:"clean-ip"` - CleanPort uint16 `json:"clean-port"` - Account WarpAccount +type MasqueOptions struct { + Enable bool `json:"enable"` + Server string `json:"server"` + Port int `json:"port"` + ServerName string `json:"server_name"` + Auth string `json:"auth"` + ALPN []string `json:"alpn"` } func DefaultHiddifyOptions() *HiddifyOptions { - return &HiddifyOptions{ - DNSOptions: DNSOptions{ - RemoteDnsAddress: "1.1.1.1", - RemoteDnsDomainStrategy: option.DomainStrategy(dns.DomainStrategyAsIS), - DirectDnsAddress: "1.1.1.1", - DirectDnsDomainStrategy: option.DomainStrategy(dns.DomainStrategyAsIS), - IndependentDNSCache: false, - EnableFakeDNS: false, - EnableDNSRouting: false, - }, - InboundOptions: InboundOptions{ - EnableTun: false, - SetSystemProxy: false, - MixedPort: 12334, - TProxyPort: 12335, - LocalDnsPort: 16450, - MTU: 9000, - StrictRoute: true, - TUNStack: "mixed", - }, - URLTestOptions: URLTestOptions{ - ConnectionTestUrl: "http://cp.cloudflare.com/", - URLTestInterval: DurationInSeconds(600), - // URLTestIdleTimeout: DurationInSeconds(6000), - }, - RouteOptions: RouteOptions{ - ResolveDestination: false, - IPv6Mode: option.DomainStrategy(dns.DomainStrategyAsIS), - BypassLAN: false, - AllowConnectionFromLAN: false, - }, - LogLevel: "warn", - // LogFile: "/dev/null", - LogFile: "box.log", - Region: "other", - EnableClashApi: true, - ClashApiPort: 16756, - ClashApiSecret: "", - // GeoIPPath: "geoip.db", - // GeoSitePath: "geosite.db", - Rules: []Rule{}, - Mux: MuxOptions{ - Enable: false, - Padding: true, - MaxStreams: 8, - Protocol: "h2mux", - }, - TLSTricks: TLSTricks{ - EnableFragment: false, - FragmentSize: "10-100", - FragmentSleep: "50-200", - MixedSNICase: false, - EnablePadding: false, - PaddingSize: "1200-1500", - }, - UseXrayCoreWhenPossible: false, - } + return &HiddifyOptions{ + DNSOptions: DNSOptions{ + RemoteDnsAddress: "1.1.1.1", + RemoteDnsDomainStrategy: option.DomainStrategy(dns.DomainStrategyAsIS), + DirectDnsAddress: "1.1.1.1", + DirectDnsDomainStrategy: option.DomainStrategy(dns.DomainStrategyAsIS), + IndependentDNSCache: false, + EnableFakeDNS: false, + EnableDNSRouting: false, + }, + InboundOptions: InboundOptions{ + EnableTun: false, + SetSystemProxy: false, + MixedPort: 12334, + TProxyPort: 12335, + LocalDnsPort: 16450, + MTU: 9000, + StrictRoute: true, + TUNStack: "mixed", + }, + URLTestOptions: URLTestOptions{ + ConnectionTestUrl: "http://cp.cloudflare.com/", + URLTestInterval: DurationInSeconds(600), + }, + RouteOptions: RouteOptions{ + ResolveDestination: false, + IPv6Mode: option.DomainStrategy(dns.DomainStrategyAsIS), + BypassLAN: false, + AllowConnectionFromLAN: false, + ExtraBypassCIDRs: []string{}, + }, + LogLevel: "warn", + LogFile: "box.log", + Region: "other", + EnableClashApi: true, + ClashApiPort: 16756, + ClashApiSecret: "", + ClashApiHost: "127.0.0.1", + GeoRulesBaseURL: "https://raw.githubusercontent.com/hiddify/hiddify-geo", + Rules: []Rule{}, + Mux: MuxOptions{ + Enable: false, + Padding: true, + MaxStreams: 8, + Protocol: "h2mux", + }, + TLSTricks: TLSTricks{ + EnableFragment: false, + FragmentSize: "10-100", + FragmentSleep: "50-200", + MixedSNICase: false, + EnablePadding: false, + PaddingSize: "1200-1500", + EnableECH: false, + ECHConfig: "", + ECHConfigPath: "", + EnableReality: false, + RealityPublicKey: "", + RealityShortID: "", + }, + UseXrayCoreWhenPossible: false, + } } diff --git a/config/outbound.go b/config/outbound.go index 73e08863..c07e5c76 100644 --- a/config/outbound.go +++ b/config/outbound.go @@ -1,184 +1,217 @@ package config import ( - "encoding/json" - "fmt" - "net" - - C "github.com/sagernet/sing-box/constant" - "github.com/sagernet/sing-box/option" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/option" ) type outboundMap map[string]interface{} func patchOutboundMux(base option.Outbound, configOpt HiddifyOptions, obj outboundMap) outboundMap { - if configOpt.Mux.Enable { - multiplex := option.OutboundMultiplexOptions{ - Enabled: true, - Padding: configOpt.Mux.Padding, - MaxStreams: configOpt.Mux.MaxStreams, - Protocol: configOpt.Mux.Protocol, - } - obj["multiplex"] = multiplex - // } else { - // delete(obj, "multiplex") - } - return obj + if configOpt.Mux.Enable { + multiplex := option.OutboundMultiplexOptions{ + Enabled: true, + Padding: configOpt.Mux.Padding, + MaxStreams: configOpt.Mux.MaxStreams, + Protocol: configOpt.Mux.Protocol, + } + obj["multiplex"] = multiplex + } + return obj } func patchOutboundTLSTricks(base option.Outbound, configOpt HiddifyOptions, obj outboundMap) outboundMap { - if base.Type == C.TypeSelector || base.Type == C.TypeURLTest || base.Type == C.TypeBlock || base.Type == C.TypeDNS { - return obj - } - if isOutboundReality(base) { - return obj - } - - var tls *option.OutboundTLSOptions - var transport *option.V2RayTransportOptions - if base.VLESSOptions.OutboundTLSOptionsContainer.TLS != nil { - tls = base.VLESSOptions.OutboundTLSOptionsContainer.TLS - transport = base.VLESSOptions.Transport - } else if base.TrojanOptions.OutboundTLSOptionsContainer.TLS != nil { - tls = base.TrojanOptions.OutboundTLSOptionsContainer.TLS - transport = base.TrojanOptions.Transport - } else if base.VMessOptions.OutboundTLSOptionsContainer.TLS != nil { - tls = base.VMessOptions.OutboundTLSOptionsContainer.TLS - transport = base.VMessOptions.Transport - } - if base.Type == C.TypeXray { - if configOpt.TLSTricks.EnableFragment { - if obj["xray_fragment"] == nil || obj["xray_fragment"].(map[string]any)["packets"] == "" { - obj["xray_fragment"] = map[string]any{ - "packets": "tlshello", - "length": configOpt.TLSTricks.FragmentSize, - "interval": configOpt.TLSTricks.FragmentSleep, - } - } - } - } - if base.Type == C.TypeDirect { - return patchOutboundFragment(base, configOpt, obj) - } - - if tls == nil || !tls.Enabled || transport == nil { - return obj - } - - if transport.Type != C.V2RayTransportTypeWebsocket && transport.Type != C.V2RayTransportTypeGRPC && transport.Type != C.V2RayTransportTypeHTTPUpgrade { - return obj - } - - if outtls, ok := obj["tls"].(map[string]interface{}); ok { - obj = patchOutboundFragment(base, configOpt, obj) - tlsTricks := tls.TLSTricks - if tlsTricks == nil { - tlsTricks = &option.TLSTricksOptions{} - } - tlsTricks.MixedCaseSNI = tlsTricks.MixedCaseSNI || configOpt.TLSTricks.MixedSNICase - - if configOpt.TLSTricks.EnablePadding { - tlsTricks.PaddingMode = "random" - tlsTricks.PaddingSize = configOpt.TLSTricks.PaddingSize - // fmt.Printf("--------------------%+v----%+v", tlsTricks.PaddingSize, configOpt) - outtls["utls"] = map[string]interface{}{ - "enabled": true, - "fingerprint": "custom", - } - } - - outtls["tls_tricks"] = tlsTricks - // if tlsTricks.MixedCaseSNI || tlsTricks.PaddingMode != "" { - // // } else { - // // tls["tls_tricks"] = nil - // } - // fmt.Printf("-------%+v------------- ", tlsTricks) - } - return obj + if base.Type == C.TypeSelector || base.Type == C.TypeURLTest || base.Type == C.TypeBlock || base.Type == C.TypeDNS { + return obj + } + if isOutboundReality(base, obj) { + return obj + } + + // Xray-specific fragment is no longer supported here under v1.13. + // Determine TLS and transport from JSON object for v1.13 + var tlsEnabled bool + if tlsMap, ok := obj["tls"].(map[string]any); ok { + if enabled, ok := tlsMap["enabled"].(bool); ok { + tlsEnabled = enabled + } + } + transportType := "" + if trMap, ok := obj["transport"].(map[string]any); ok { + if t, ok := trMap["type"].(string); ok { + transportType = t + } + } + if !tlsEnabled { + return obj + } + if transportType != C.V2RayTransportTypeWebsocket && transportType != C.V2RayTransportTypeGRPC && transportType != C.V2RayTransportTypeHTTPUpgrade { + return obj + } + + if outtls, ok := obj["tls"].(map[string]interface{}); ok { + obj = patchOutboundFragment(base, configOpt, obj) + var tlsTricks map[string]any + if existing, ok := outtls["tls_tricks"].(map[string]any); ok { + tlsTricks = existing + } else { + tlsTricks = map[string]any{} + } + if configOpt.TLSTricks.MixedSNICase { + tlsTricks["mixed_case_sni"] = true + } + + if configOpt.TLSTricks.EnablePadding { + tlsTricks["padding_mode"] = "random" + tlsTricks["padding_size"] = configOpt.TLSTricks.PaddingSize + outtls["utls"] = map[string]interface{}{ + "enabled": true, + "fingerprint": "custom", + } + } + + outtls["tls_tricks"] = tlsTricks + // if tlsTricks.MixedCaseSNI || tlsTricks.PaddingMode != "" { + // // } else { + // // tls["tls_tricks"] = nil + // } + } + return obj } func patchOutboundFragment(base option.Outbound, configOpt HiddifyOptions, obj outboundMap) outboundMap { - if configOpt.TLSTricks.EnableFragment { - obj["tcp_fast_open"] = false - obj["tls_fragment"] = option.TLSFragmentOptions{ - Enabled: configOpt.TLSTricks.EnableFragment, - Size: configOpt.TLSTricks.FragmentSize, - Sleep: configOpt.TLSTricks.FragmentSleep, - } - - } - - return obj + if configOpt.TLSTricks.EnableFragment { + obj["tcp_fast_open"] = false + obj["tls_fragment"] = map[string]any{ + "enabled": configOpt.TLSTricks.EnableFragment, + "size": configOpt.TLSTricks.FragmentSize, + "sleep": configOpt.TLSTricks.FragmentSleep, + } + } + + return obj } -func isOutboundReality(base option.Outbound) bool { - // this function checks reality status ONLY FOR VLESS. - // Some other protocols can also use reality, but it's discouraged as stated in the reality document - if base.Type != C.TypeVLESS { - return false - } - if base.VLESSOptions.OutboundTLSOptionsContainer.TLS == nil { - return false - } - if base.VLESSOptions.OutboundTLSOptionsContainer.TLS.Reality == nil { - return false - } - return base.VLESSOptions.OutboundTLSOptionsContainer.TLS.Reality.Enabled +func isOutboundReality(base option.Outbound, obj outboundMap) bool { + // this function checks reality status ONLY FOR VLESS. + // Some other protocols can also use reality, but it's discouraged as stated in the reality document + if base.Type != C.TypeVLESS { + return false + } + if tlsMap, ok := obj["tls"].(map[string]any); ok { + if reality, ok := tlsMap["reality"].(map[string]any); ok { + if enabled, ok := reality["enabled"].(bool); ok { + return enabled + } + } + } + return false } func patchOutbound(base option.Outbound, configOpt HiddifyOptions, staticIpsDns map[string][]string) (*option.Outbound, string, error) { - formatErr := func(err error) error { - return fmt.Errorf("error patching outbound[%s][%s]: %w", base.Tag, base.Type, err) - } - err := patchWarp(&base, &configOpt, true, staticIpsDns) - if err != nil { - return nil, "", formatErr(err) - } - var outbound option.Outbound - - jsonData, err := base.MarshalJSON() - if err != nil { - return nil, "", formatErr(err) - } - - var obj outboundMap - err = json.Unmarshal(jsonData, &obj) - if err != nil { - return nil, "", formatErr(err) - } - var serverDomain string - if detour, ok := obj["detour"].(string); !ok || detour == "" { - if server, ok := obj["server"].(string); ok { - if server != "" && net.ParseIP(server) == nil { - serverDomain = fmt.Sprintf("full:%s", server) - } - } - } - - obj = patchOutboundTLSTricks(base, configOpt, obj) - - switch base.Type { - case C.TypeVMess, C.TypeVLESS, C.TypeTrojan, C.TypeShadowsocks: - obj = patchOutboundMux(base, configOpt, obj) - } - - modifiedJson, err := json.Marshal(obj) - if err != nil { - return nil, "", formatErr(err) - } - - err = outbound.UnmarshalJSON(modifiedJson) - if err != nil { - return nil, "", formatErr(err) - } - - return &outbound, serverDomain, nil + // formatErr := func(err error) error { + // return fmt.Errorf("error patching outbound[%s][%s]: %w", base.Tag, base.Type, err) + // } + // if err := patchWarp(&base, &configOpt, true, staticIpsDns); err != nil { + // return nil, "", formatErr(err) + // } + // Apply MUX options in typed way for common outbounds + if configOpt.Mux.Enable { + mux := option.OutboundMultiplexOptions{ + Enabled: true, + Padding: configOpt.Mux.Padding, + MaxStreams: configOpt.Mux.MaxStreams, + Protocol: configOpt.Mux.Protocol, + } + switch base.Type { + case C.TypeVMess: + if o, ok := base.Options.(option.VMessOutboundOptions); ok { + o.Multiplex = &mux + base.Options = o + } + case C.TypeVLESS: + if o, ok := base.Options.(option.VLESSOutboundOptions); ok { + o.Multiplex = &mux + base.Options = o + } + case C.TypeTrojan: + if o, ok := base.Options.(option.TrojanOutboundOptions); ok { + o.Multiplex = &mux + base.Options = o + } + } + } + + // Apply TLS tweaks in typed way when TLS is already present and enabled + applyTLSTweaks := func(tls *option.OutboundTLSOptions) { + if tls == nil || !tls.Enabled { + return + } + if configOpt.TLSTricks.EnableFragment { + tls.Fragment = true + } + if configOpt.TLSTricks.MixedSNICase || configOpt.TLSTricks.EnablePadding { + // No direct mixed-case or padding size fields in v1.13; enable uTLS with custom fp as closest behavior + if tls.UTLS == nil { + tls.UTLS = &option.OutboundUTLSOptions{} + } + tls.UTLS.Enabled = true + if tls.UTLS.Fingerprint == "" { + tls.UTLS.Fingerprint = "custom" + } + } + if configOpt.TLSTricks.EnableECH { + if tls.ECH == nil { + tls.ECH = &option.OutboundECHOptions{} + } + tls.ECH.Enabled = true + // Prefer inline config if provided; otherwise use path + if configOpt.TLSTricks.ECHConfig != "" { + tls.ECH.Config = []string{configOpt.TLSTricks.ECHConfig} + tls.ECH.ConfigPath = "" + } else if configOpt.TLSTricks.ECHConfigPath != "" { + tls.ECH.Config = nil + tls.ECH.ConfigPath = configOpt.TLSTricks.ECHConfigPath + } + } + if configOpt.TLSTricks.EnableReality { + if tls.Reality == nil { + tls.Reality = &option.OutboundRealityOptions{} + } + tls.Reality.Enabled = true + if configOpt.TLSTricks.RealityPublicKey != "" { + tls.Reality.PublicKey = configOpt.TLSTricks.RealityPublicKey + } + if configOpt.TLSTricks.RealityShortID != "" { + tls.Reality.ShortID = configOpt.TLSTricks.RealityShortID + } + } + } + switch base.Type { + case C.TypeVMess: + if o, ok := base.Options.(option.VMessOutboundOptions); ok { + if o.OutboundTLSOptionsContainer.TLS != nil { + applyTLSTweaks(o.OutboundTLSOptionsContainer.TLS) + base.Options = o + } + } + case C.TypeVLESS: + if o, ok := base.Options.(option.VLESSOutboundOptions); ok { + if o.OutboundTLSOptionsContainer.TLS != nil { + applyTLSTweaks(o.OutboundTLSOptionsContainer.TLS) + base.Options = o + } + } + case C.TypeTrojan: + if o, ok := base.Options.(option.TrojanOutboundOptions); ok { + if o.OutboundTLSOptionsContainer.TLS != nil { + applyTLSTweaks(o.OutboundTLSOptionsContainer.TLS) + base.Options = o + } + } + } + return &base, "", nil } - -// func (o outboundMap) transportType() string { -// if transport, ok := o["transport"].(map[string]interface{}); ok { -// if transportType, ok := transport["type"].(string); ok { -// return transportType // } // } // return "" diff --git a/config/parser.go b/config/parser.go index b6e23de8..9622bbcf 100644 --- a/config/parser.go +++ b/config/parser.go @@ -2,21 +2,20 @@ package config import ( "bytes" - "context" + json "github.com/goccy/go-json" _ "embed" - "encoding/json" + "context" "fmt" "os" "path/filepath" - "github.com/hiddify/ray2sing/ray2sing" "github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing/common/batch" SJ "github.com/sagernet/sing/common/json" "github.com/xmdhs/clash2singbox/convert" "github.com/xmdhs/clash2singbox/model/clash" - "gopkg.in/yaml.v3" + "github.com/goccy/go-yaml" ) //go:embed config.json.template @@ -76,7 +75,7 @@ func ParseConfigContent(contentstr string, debug bool, configOpt *HiddifyOptions return patchConfig(newContent, "SingboxParser", configOpt) } - v2rayStr, err := ray2sing.Ray2Singbox(string(content), configOpt.UseXrayCoreWhenPossible) + v2rayStr, err := convertV2ray(string(content), configOpt.UseXrayCoreWhenPossible) if err == nil { return patchConfig([]byte(v2rayStr), "V2rayParser", configOpt) } @@ -111,10 +110,10 @@ func patchConfig(content []byte, name string, configOpt *HiddifyOptions) ([]byte for _, base := range options.Outbounds { out := base b.Go(base.Tag, func() (*option.Outbound, error) { - err := patchWarp(&out, configOpt, false, nil) - if err != nil { - return nil, fmt.Errorf("[Warp] patch warp error: %w", err) - } + // err := patchWarp(&out, configOpt, false, nil) + // if err != nil { + // return nil, fmt.Errorf("[Warp] patch warp error: %w", err) + // } // options.Outbounds[i] = base return &out, nil }) diff --git a/config/server.go b/config/server.go index 6824220f..11c18e38 100644 --- a/config/server.go +++ b/config/server.go @@ -1,7 +1,8 @@ package config import ( - context "context" + "context" + json "github.com/goccy/go-json" "fmt" "log" "net" @@ -15,7 +16,6 @@ import ( type server struct { UnimplementedCoreServiceServer } - func String(s string) *string { return &s } @@ -33,25 +33,22 @@ func (s *server) ParseConfig(ctx context.Context, in *ParseConfigRequest) (*Pars } func (s *server) GenerateFullConfig(ctx context.Context, in *GenerateConfigRequest) (*GenerateConfigResponse, error) { - os.Chdir(filepath.Dir(in.Path)) - content, err := os.ReadFile(in.Path) - if err != nil { - return nil, err - } - var options option.Options - err = options.UnmarshalJSON(content) - if err != nil { - return nil, err - } - if err != nil { - return nil, err - } - config, err := BuildConfigJson(*DefaultHiddifyOptions(), options) - if err != nil { - return nil, err - } - return &GenerateConfigResponse{ - Config: config, + os.Chdir(filepath.Dir(in.Path)) + content, err := os.ReadFile(in.Path) + if err != nil { + return nil, err + } + var options option.Options + // Parse with standard encoding/json (yields generic maps for Outbound.Options) + if err := json.Unmarshal(content, &options); err != nil { + return nil, err + } + config, err := BuildConfigJson(*DefaultHiddifyOptions(), options) + if err != nil { + return nil, err + } + return &GenerateConfigResponse{ + Config: config, }, nil } diff --git a/config/types.go b/config/types.go index 9fe6cc5c..bd281118 100644 --- a/config/types.go +++ b/config/types.go @@ -1,7 +1,7 @@ package config import ( - "encoding/json" + json "github.com/goccy/go-json" "time" ) diff --git a/config/v2ray_adapter.go b/config/v2ray_adapter.go new file mode 100644 index 00000000..618ab902 --- /dev/null +++ b/config/v2ray_adapter.go @@ -0,0 +1,7 @@ +package config + +import "fmt" + +func convertV2ray(content string, useXrayWhenPossible bool) (string, error) { + return "", fmt.Errorf("v2ray config conversion is disabled") +} diff --git a/config/warp.go b/config/warp.go deleted file mode 100644 index 36a3416b..00000000 --- a/config/warp.go +++ /dev/null @@ -1,270 +0,0 @@ -package config - -import ( - "encoding/base64" - "fmt" - "log/slog" - "net/netip" - "os" - "strings" - - "github.com/bepass-org/warp-plus/warp" - "github.com/hiddify/hiddify-core/v2/common" - C "github.com/sagernet/sing-box/constant" - - // "github.com/bepass-org/wireguard-go/warp" - "github.com/hiddify/hiddify-core/v2/db" - - "github.com/sagernet/sing-box/option" - T "github.com/sagernet/sing-box/option" -) - -type SingboxConfig struct { - Type string `json:"type"` - Tag string `json:"tag"` - Server string `json:"server"` - ServerPort int `json:"server_port"` - LocalAddress []string `json:"local_address"` - PrivateKey string `json:"private_key"` - PeerPublicKey string `json:"peer_public_key"` - Reserved []int `json:"reserved"` - MTU int `json:"mtu"` -} - -func wireGuardToSingbox(wgConfig WarpWireguardConfig, server string, port uint16) (*T.Outbound, error) { - clientID, _ := base64.StdEncoding.DecodeString(wgConfig.ClientID) - if len(clientID) < 2 { - clientID = []byte{0, 0, 0} - } - out := T.Outbound{ - Type: "wireguard", - Tag: "WARP", - WireGuardOptions: T.WireGuardOutboundOptions{ - ServerOptions: T.ServerOptions{ - Server: server, - ServerPort: port, - }, - - PrivateKey: wgConfig.PrivateKey, - PeerPublicKey: wgConfig.PeerPublicKey, - Reserved: []uint8{clientID[0], clientID[1], clientID[2]}, - // Reserved: []uint8{0, 0, 0}, - MTU: 1330, - }, - } - ips := []string{wgConfig.LocalAddressIPv4 + "/24", wgConfig.LocalAddressIPv6 + "/128"} - - for _, addr := range ips { - if addr == "" { - continue - } - prefix, err := netip.ParsePrefix(addr) - if err != nil { - return nil, err // Handle the error appropriately - } - out.WireGuardOptions.LocalAddress = append(out.WireGuardOptions.LocalAddress, prefix) - } - return &out, nil -} - -func getRandomIP() string { - ipPort, err := warp.RandomWarpEndpoint(true, true) - if err == nil { - return ipPort.Addr().String() - } - return "engage.cloudflareclient.com" -} - -func generateWarp(license string, host string, port uint16, fakePackets string, fakePacketsSize string, fakePacketsDelay string, fakePacketsMode string) (*T.Outbound, error) { - _, _, wgConfig, err := GenerateWarpInfo(license, "", "") - if err != nil { - return nil, err - } - if wgConfig == nil { - return nil, fmt.Errorf("invalid warp config") - } - - return GenerateWarpSingbox(*wgConfig, host, port, fakePackets, fakePacketsSize, fakePacketsDelay, fakePacketsMode) -} - -func GenerateWarpSingbox(wgConfig WarpWireguardConfig, host string, port uint16, fakePackets string, fakePacketsSize string, fakePacketsDelay string, fakePacketMode string) (*T.Outbound, error) { - if host == "" { - host = "auto4" - } - - if (host == "auto" || host == "auto4" || host == "auto6") && fakePackets == "" { - fakePackets = "1-3" - } - if fakePackets != "" && fakePacketsSize == "" { - fakePacketsSize = "10-30" - } - if fakePackets != "" && fakePacketsDelay == "" { - fakePacketsDelay = "10-30" - } - singboxConfig, err := wireGuardToSingbox(wgConfig, host, port) - if err != nil { - fmt.Printf("%v %v", singboxConfig, err) - return nil, err - } - - singboxConfig.WireGuardOptions.FakePackets = fakePackets - singboxConfig.WireGuardOptions.FakePacketsSize = fakePacketsSize - singboxConfig.WireGuardOptions.FakePacketsDelay = fakePacketsDelay - singboxConfig.WireGuardOptions.FakePacketsMode = fakePacketMode - - return singboxConfig, nil -} - -func GenerateWarpInfo(license string, oldAccountId string, oldAccessToken string) (*warp.Identity, string, *WarpWireguardConfig, error) { - if oldAccountId != "" && oldAccessToken != "" { - err := warp.DeleteDevice(oldAccessToken, oldAccountId) - if err != nil { - fmt.Printf("Error in removing old device: %v\n", err) - } else { - fmt.Printf("Old Device Removed") - } - } - l := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) - identity, err := warp.CreateIdentityOnly(l, license) - res := "Error!" - var warpcfg WarpWireguardConfig - if err == nil { - res = "Success" - res = fmt.Sprintf("Warp+ enabled: %t\n", identity.Account.WarpPlus) - res += fmt.Sprintf("\nAccount type: %s\n", identity.Account.AccountType) - warpcfg = WarpWireguardConfig{ - PrivateKey: identity.PrivateKey, - PeerPublicKey: identity.Config.Peers[0].PublicKey, - LocalAddressIPv4: identity.Config.Interface.Addresses.V4, - LocalAddressIPv6: identity.Config.Interface.Addresses.V6, - ClientID: identity.Config.ClientID, - } - } - - return &identity, res, &warpcfg, err -} - -func getOrGenerateWarpLocallyIfNeeded(warpOptions *WarpOptions) WarpWireguardConfig { - if warpOptions.WireguardConfig.PrivateKey != "" { - return warpOptions.WireguardConfig - } - table := db.GetTable[WarpOptions]() - dbWarpOptions, err := table.Get(warpOptions.Id) - if err == nil && dbWarpOptions.WireguardConfig.PrivateKey != "" { - return warpOptions.WireguardConfig - } - license := "" - if len(warpOptions.Id) == 26 { // warp key is 26 characters long - license = warpOptions.Id - } else if len(warpOptions.Id) > 28 && warpOptions.Id[2] == '_' { // warp key is 26 characters long - license = warpOptions.Id[3:] - } - - accountidentity, _, wireguardConfig, err := GenerateWarpInfo(license, warpOptions.Account.AccountID, warpOptions.Account.AccessToken) - if err != nil { - return WarpWireguardConfig{} - } - warpOptions.Account = WarpAccount{ - AccountID: accountidentity.ID, - AccessToken: accountidentity.Token, - } - warpOptions.WireguardConfig = *wireguardConfig - table.UpdateInsert(warpOptions) - - return *wireguardConfig -} - -func patchWarp(base *option.Outbound, configOpt *HiddifyOptions, final bool, staticIpsDns map[string][]string) error { - if base.Type == C.TypeCustom { - if warp, ok := base.CustomOptions["warp"].(map[string]interface{}); ok { - key, _ := warp["key"].(string) - host, _ := warp["host"].(string) - port, _ := warp["port"].(uint16) - detour, _ := warp["detour"].(string) - fakePackets, _ := warp["fake_packets"].(string) - fakePacketsSize, _ := warp["fake_packets_size"].(string) - fakePacketsDelay, _ := warp["fake_packets_delay"].(string) - fakePacketsMode, _ := warp["fake_packets_mode"].(string) - var warpOutbound *T.Outbound - var err error - - is_saved_key := len(key) > 1 && key[0] == 'p' - - if (configOpt == nil || !final) && is_saved_key { - return nil - } - var wireguardConfig WarpWireguardConfig - if is_saved_key { - var warpOpt *WarpOptions - if key == "p1" { - warpOpt = &configOpt.Warp - } else if key == "p2" { - warpOpt = &configOpt.Warp2 - } else { - warpOpt = &WarpOptions{ - Id: key, - } - } - warpOpt.Id = key - - wireguardConfig = getOrGenerateWarpLocallyIfNeeded(warpOpt) - } else { - _, _, wgConfig, err := GenerateWarpInfo(key, "", "") - if err != nil { - return err - } - wireguardConfig = *wgConfig - } - warpOutbound, err = GenerateWarpSingbox(wireguardConfig, host, port, fakePackets, fakePacketsSize, fakePacketsDelay, fakePacketsMode) - if err != nil { - fmt.Printf("Error generating warp config: %v", err) - return err - } - warpOutbound.WireGuardOptions.Detour = detour - base.Type = C.TypeWireGuard - base.WireGuardOptions = warpOutbound.WireGuardOptions - } - } - - if final && base.Type == C.TypeWireGuard { - host := base.WireGuardOptions.Server - - if host == "default" || host == "random" || host == "auto" || host == "auto4" || host == "auto6" || isBlockedDomain(host) { - // if base.WireGuardOptions.Detour != "" { - // base.WireGuardOptions.Server = "162.159.192.1" - // } else { - rndDomain := strings.ToLower(generateRandomString(20)) - staticIpsDns[rndDomain] = []string{} - if host != "auto4" { - if host == "auto6" || common.CanConnectIPv6() { - randomIpPort, _ := warp.RandomWarpEndpoint(false, true) - staticIpsDns[rndDomain] = append(staticIpsDns[rndDomain], randomIpPort.Addr().String()) - } - } - if host != "auto6" { - randomIpPort, _ := warp.RandomWarpEndpoint(true, false) - staticIpsDns[rndDomain] = append(staticIpsDns[rndDomain], randomIpPort.Addr().String()) - } - base.WireGuardOptions.Server = rndDomain - // } - } - if base.WireGuardOptions.ServerPort == 0 { - port := warp.RandomWarpPort() - base.WireGuardOptions.ServerPort = port - } - - if base.WireGuardOptions.Detour != "" { - if base.WireGuardOptions.MTU < 100 { - base.WireGuardOptions.MTU = 1280 - } - base.WireGuardOptions.FakePackets = "" - base.WireGuardOptions.FakePacketsDelay = "" - base.WireGuardOptions.FakePacketsSize = "" - } - // if base.WireGuardOptions.Detour == "" { - // base.WireGuardOptions.GSO = runtime.GOOS != "windows" - // } - } - - return nil -} diff --git a/config/warp_account.go b/config/warp_account.go deleted file mode 100644 index 2578e35b..00000000 --- a/config/warp_account.go +++ /dev/null @@ -1,50 +0,0 @@ -package config - -import ( - "encoding/json" -) - -type WarpAccount struct { - AccountID string `json:"account-id"` - AccessToken string `json:"access-token"` -} - -type WarpWireguardConfig struct { - PrivateKey string `json:"private-key"` - LocalAddressIPv4 string `json:"local-address-ipv4"` - LocalAddressIPv6 string `json:"local-address-ipv6"` - PeerPublicKey string `json:"peer-public-key"` - ClientID string `json:"client-id"` -} - -type WarpGenerationResponse struct { - WarpAccount - Log string `json:"log"` - Config WarpWireguardConfig `json:"config"` -} - -func GenerateWarpAccount(licenseKey string, accountId string, accessToken string) (string, error) { - identity, log, wg, err := GenerateWarpInfo(licenseKey, accountId, accessToken) - if err != nil { - return "", err - } - - warpAccount := WarpAccount{ - AccountID: identity.ID, - AccessToken: identity.Token, - } - warpConfig := WarpWireguardConfig{ - PrivateKey: wg.PrivateKey, - LocalAddressIPv4: wg.LocalAddressIPv4, - LocalAddressIPv6: wg.LocalAddressIPv6, - PeerPublicKey: wg.PeerPublicKey, - ClientID: wg.ClientID, - } - response := WarpGenerationResponse{warpAccount, log, warpConfig} - - responseJson, err := json.Marshal(response) - if err != nil { - return "", err - } - return string(responseJson), nil -} diff --git a/custom/custom.go b/custom/custom.go index ff990218..76737ef3 100644 --- a/custom/custom.go +++ b/custom/custom.go @@ -6,13 +6,11 @@ package main import "C" import ( - "encoding/json" "fmt" "os" "unsafe" "github.com/hiddify/hiddify-core/bridge" - "github.com/hiddify/hiddify-core/config" pb "github.com/hiddify/hiddify-core/hiddifyrpc" v2 "github.com/hiddify/hiddify-core/v2" @@ -133,37 +131,7 @@ func emptyOrErrorC(err error) *C.char { //export generateWarpConfig func generateWarpConfig(licenseKey *C.char, accountId *C.char, accessToken *C.char) (CResp *C.char) { - res, err := v2.GenerateWarpConfig(&pb.GenerateWarpConfigRequest{ - LicenseKey: C.GoString(licenseKey), - AccountId: C.GoString(accountId), - AccessToken: C.GoString(accessToken), - }) - if err != nil { - return C.CString(fmt.Sprint("error: ", err.Error())) - } - warpAccount := config.WarpAccount{ - AccountID: res.Account.AccountId, - AccessToken: res.Account.AccessToken, - } - warpConfig := config.WarpWireguardConfig{ - PrivateKey: res.Config.PrivateKey, - LocalAddressIPv4: res.Config.LocalAddressIpv4, - LocalAddressIPv6: res.Config.LocalAddressIpv6, - PeerPublicKey: res.Config.PeerPublicKey, - ClientID: res.Config.ClientId, - } - log := res.Log - response := &config.WarpGenerationResponse{ - WarpAccount: warpAccount, - Log: log, - Config: warpConfig, - } - - responseJson, err := json.Marshal(response) - if err != nil { - return C.CString("") - } - return C.CString(string(responseJson)) + return C.CString("") } func main() {} diff --git a/docker/Dockerfile b/docker/Dockerfile index 2d59d426..fac95edf 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,6 +1,7 @@ FROM alpine:latest +ARG VERSION=latest ENV CONFIG='https://raw.githubusercontent.com/ircfspace/warpsub/main/export/warp#WARP%20(IRCF)' -ENV VERSION=v3.1.8 +ENV VERSION=${VERSION} WORKDIR /hiddify RUN apk add curl tar gzip libc6-compat # iptables ip6tables @@ -15,6 +16,10 @@ RUN echo "architecture: $(apk --print-arch)" && \ s390x) ARCH=s390x ;; \ *) echo "Unsupported architecture: $(apk --print-arch) $(uname -m)" && exit 1 ;; \ esac && \ + if [ "$VERSION" = "latest" ]; then \ + VERSION=$(curl -s https://api.github.com/repos/hiddify/hiddify-core/releases/latest | grep tag_name | cut -d '"' -f4); \ + fi && \ + echo "Resolved VERSION=$VERSION" && \ echo "Downloading https://github.com/hiddify/hiddify-core/releases/download/${VERSION}/hiddify-cli-linux-$ARCH.tar.gz" && \ curl -L -o hiddify-cli.tar.gz https://github.com/hiddify/hiddify-core/releases/download/${VERSION}/hiddify-cli-linux-$ARCH.tar.gz && \ tar -xzf hiddify-cli.tar.gz && rm hiddify-cli.tar.gz diff --git a/extension/extension.go b/extension/extension.go index 09dc4e72..7db4e9b2 100644 --- a/extension/extension.go +++ b/extension/extension.go @@ -1,7 +1,7 @@ package extension import ( - "encoding/json" + json "github.com/goccy/go-json" "github.com/hiddify/hiddify-core/config" "github.com/hiddify/hiddify-core/extension/ui" diff --git a/extension/interface.go b/extension/interface.go index 60cbb561..0113e87b 100644 --- a/extension/interface.go +++ b/extension/interface.go @@ -1,12 +1,13 @@ package extension import ( - "fmt" + "fmt" - "github.com/hiddify/hiddify-core/v2/db" - "github.com/sagernet/sing-box/log" + "github.com/hiddify/hiddify-core/v2/db" + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/log" - "github.com/hiddify/hiddify-core/v2/service_manager" + "github.com/hiddify/hiddify-core/v2/service_manager" ) var ( @@ -43,17 +44,24 @@ func loadExtension(factory ExtensionFactory) error { extension.init(factory.Id) // fmt.Printf("Registered extension: %+v\n", extension) - enabledExtensionsMap[factory.Id] = &extension return nil } type extensionService struct { - // Storage *CacheFile + // Storage *CacheFile } -func (s *extensionService) Start() error { - table := db.GetTable[extensionData]() +func (s *extensionService) Tag() string { + return "hiddify-extension" +} + +func (s *extensionService) Type() string { + return "extension" +} + +func (s *extensionService) Start(stage adapter.StartStage) error { + table := db.GetTable[extensionData]() for _, factory := range allExtensionsMap { data, err := table.Get(factory.Id) diff --git a/extension/repository/extension_list.go b/extension/repository/extension_list.go index cfb9bf2a..8ccd5ff8 100644 --- a/extension/repository/extension_list.go +++ b/extension/repository/extension_list.go @@ -1,6 +1,6 @@ package repository import ( - _ "github.com/hiddify/hiddify-app-demo-extension/hiddify_extension" - _ "github.com/hiddify/hiddify-ip-scanner-extension/hiddify_extension" + _ "github.com/hiddify/hiddify-app-demo-extension/hiddify_extension" + // _ "github.com/hiddify/hiddify-ip-scanner-extension/hiddify_extension" // temporarily disabled: incompatible with sing-box v1.13 option.Outbound ) diff --git a/extension/ui/all_test.go b/extension/ui/all_test.go index eedd36f4..5e121cf8 100644 --- a/extension/ui/all_test.go +++ b/extension/ui/all_test.go @@ -1,14 +1,41 @@ package ui -// import ( -// "encoding/json" -// "testing" -// ) +import ( + json "github.com/goccy/go-json" + "testing" +) // // Test UnmarshalJSON for different field types -// func TestFormUnmarshalJSON(t *testing.T) { -// formJSON := `{ -// "title": "Form Example", +func TestFormUnmarshalJSON(t *testing.T) { + formJSON := `{ + "title": "Form Example", + "description": "This is a sample form.", + "fields": [ + { + "key": "inputKey", + "type": "Input", + "label": "Hi Group", + "placeholder": "Hi Group flutter", + "required": true, + "value": "D" + }, + { + "key": "passwordKey", + "type": "Password", + "label": "Password", + "required": true, + "value": "secret" + }, + { + "key": "emailKey", + "type": "Email", + "label": "Email Label", + "placeholder": "Enter your email", + "required": true, + "value": "example@example.com" + } + ] + }` // "description": "This is a sample form.", // "fields": [ // { diff --git a/extension/ui/base.go b/extension/ui/base.go index b9adc999..7dd0adfb 100644 --- a/extension/ui/base.go +++ b/extension/ui/base.go @@ -1,7 +1,7 @@ package ui import ( - "encoding/json" + json "github.com/goccy/go-json" "fmt" ) diff --git a/extension/ui/form.go b/extension/ui/form.go index f07dfc81..c9175dcb 100644 --- a/extension/ui/form.go +++ b/extension/ui/form.go @@ -1,8 +1,7 @@ package ui // import ( -// "encoding/json" -// "fmt" +// json "github.com/goccy/go-json" // ) // // InputField represents a text input field. diff --git a/go.mod b/go.mod index 0e69779b..98e24860 100644 --- a/go.mod +++ b/go.mod @@ -1,162 +1,166 @@ module github.com/hiddify/hiddify-core -go 1.22.0 - -toolchain go1.22.3 +go 1.24.7 require ( - github.com/bepass-org/warp-plus v1.2.4 - github.com/fatih/color v1.16.0 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/hiddify/hiddify-app-demo-extension v0.0.0-20241001070003-26039f960ad6 - github.com/hiddify/hiddify-ip-scanner-extension v0.0.0-20241001070353-7ffd688b96b2 github.com/improbable-eng/grpc-web v0.15.0 - github.com/jellydator/validation v1.1.0 - github.com/kardianos/service v1.2.2 - github.com/sagernet/gomobile v0.1.4 - github.com/sagernet/sing v0.4.3 - github.com/sagernet/sing-box v1.8.9 - github.com/sagernet/sing-dns v0.2.3 - github.com/spf13/cobra v1.8.0 - github.com/xmdhs/clash2singbox v0.0.2 - golang.org/x/sys v0.25.0 - google.golang.org/grpc v1.66.0 - google.golang.org/protobuf v1.34.2 - gopkg.in/yaml.v3 v3.0.1 + github.com/sagernet/gomobile v0.1.8 + github.com/sagernet/sing v0.8.0-beta.6 + github.com/sagernet/sing-box v1.13.0-alpha.27 + github.com/sagernet/sing-dns v0.4.6 + github.com/spf13/cobra v1.10.1 + github.com/xmdhs/clash2singbox v0.1.4 + golang.org/x/sys v0.37.0 + google.golang.org/grpc v1.76.0 + google.golang.org/protobuf v1.36.10 + gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( - github.com/Yiwen-Chan/tinydb v0.0.0-20230129042445-3321642f0674 + github.com/goccy/go-json v0.10.5 + github.com/goccy/go-yaml v1.18.0 + github.com/jellydator/validation v1.1.0 + github.com/kardianos/service v1.2.2 github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca github.com/tendermint/tm-db v0.6.7 ) require ( + filippo.io/edwards25519 v1.1.0 // indirect github.com/DataDog/zstd v1.4.1 // indirect - github.com/cenkalti/backoff/v4 v4.1.1 // indirect + github.com/akutz/memconn v0.1.0 // indirect + github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect + github.com/anthropics/anthropic-sdk-go v1.14.0 // indirect + github.com/anytls/sing-anytls v0.0.11 // indirect + github.com/caddyserver/zerossl v0.1.3 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect + github.com/coder/websocket v1.8.13 // indirect + github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect + github.com/database64128/netx-go v0.1.1 // indirect + github.com/database64128/tfo-go/v2 v2.3.1 // indirect + github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v2 v2.2007.2 // indirect github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect + github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect github.com/dustin/go-humanize v1.0.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/gaissmai/bart v0.18.0 // indirect + github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect + github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.1 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/illarion/gonotify/v3 v3.0.2 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/jsimonetti/rtnetlink v1.4.0 // indirect + github.com/keybase/go-keychain v0.0.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d // indirect + github.com/mdlayher/genetlink v1.3.2 // indirect + github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 // indirect + github.com/mdlayher/sdnotify v1.0.0 // indirect + github.com/mdlayher/socket v0.5.1 // indirect + github.com/metacubex/utls v1.8.3 // indirect + github.com/mholt/acmez/v3 v3.1.2 // indirect + github.com/mitchellh/go-ps v1.0.0 // indirect + github.com/onsi/gomega v1.33.1 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/rodaine/table v1.1.1 // indirect + github.com/prometheus-community/pro-bing v0.4.0 // indirect github.com/rs/cors v1.7.0 // indirect - go.etcd.io/bbolt v1.3.6 // indirect + github.com/safchain/ethtool v0.3.0 // indirect + github.com/sagernet/cors v1.2.1 // indirect + github.com/sagernet/fswatch v0.1.1 // indirect + github.com/sagernet/nftables v0.3.0-beta.4 // indirect + github.com/sagernet/tailscale v1.86.5-sing-box-1.13-mod.4 // indirect + github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect + github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect + github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect + github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a // indirect + github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect + github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect + github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 // indirect + github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.etcd.io/bbolt v1.3.11 // indirect + go.uber.org/zap/exp v0.3.0 // indirect + go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect + golang.org/x/term v0.36.0 // indirect + golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect + golang.zx2c4.com/wireguard/windows v0.5.3 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect nhooyr.io/websocket v1.8.6 // indirect ) require ( - berty.tech/go-libtor v1.0.385 // indirect github.com/ajg/form v1.5.1 // indirect github.com/andybalholm/brotli v1.1.0 // indirect - github.com/caddyserver/certmagic v0.20.0 // indirect - github.com/cloudflare/circl v1.4.0 // indirect + github.com/caddyserver/certmagic v0.23.0 // indirect github.com/cretz/bine v0.2.0 // indirect - github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect - github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gaukas/godicttls v0.0.4 // indirect - github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 // indirect - github.com/go-chi/chi/v5 v5.0.12 // indirect - github.com/go-chi/cors v1.2.1 // indirect + github.com/go-chi/chi/v5 v5.2.2 // indirect github.com/go-chi/render v1.0.3 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/gofrs/uuid/v5 v5.2.0 // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/pprof v0.0.0-20240528025155-186aa0362fba // indirect - github.com/gorilla/websocket v1.5.3 // indirect - github.com/hashicorp/yamux v0.1.1 // indirect - github.com/hiddify/ray2sing v0.0.0-20240804185422-f340989b59a0 - github.com/imkira/go-observer/v2 v2.0.0-20230629064422-8e0b61f11f1b // indirect + github.com/gofrs/uuid/v5 v5.3.2 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 // indirect - github.com/josharian/native v1.1.0 // indirect - github.com/klauspost/compress v1.17.8 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect - github.com/libdns/alidns v1.0.3 // indirect - github.com/libdns/cloudflare v0.1.1 // indirect - github.com/libdns/libdns v0.2.2 // indirect + github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/libdns/alidns v1.0.5-libdns.v1.beta1 // indirect + github.com/libdns/cloudflare v0.2.2-0.20250708034226-c574dccb31a6 // indirect + github.com/libdns/libdns v1.1.0 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect - github.com/mholt/acmez v1.2.0 // indirect - github.com/miekg/dns v1.1.62 // indirect - github.com/onsi/ginkgo/v2 v2.19.0 // indirect - github.com/ooni/go-libtor v1.1.8 // indirect - github.com/oschwald/maxminddb-golang v1.12.0 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pierrec/lz4/v4 v4.1.14 // indirect - github.com/pion/dtls/v2 v2.2.7 // indirect - github.com/pion/logging v0.2.2 // indirect - github.com/pion/randutil v0.1.0 // indirect - github.com/pion/stun/v2 v2.0.0 // indirect - github.com/pion/transport/v2 v2.2.3 // indirect - github.com/pion/transport/v3 v3.0.1 // indirect - github.com/pion/turn/v3 v3.0.1 // indirect - github.com/pires/go-proxyproto v0.7.0 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-20 v0.4.1 // indirect - github.com/quic-go/quic-go v0.46.0 // indirect - github.com/refraction-networking/utls v1.6.7 // indirect - github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect + github.com/miekg/dns v1.1.67 // indirect + github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/quic-go/qpack v0.5.1 // indirect github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a // indirect - github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 // indirect - github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f // indirect - github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba // indirect - github.com/sagernet/quic-go v0.47.0-beta.2 // indirect - github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect - github.com/sagernet/sing-mux v0.2.0 // indirect - github.com/sagernet/sing-quic v0.2.2 // indirect - github.com/sagernet/sing-shadowsocks v0.2.7 // indirect - github.com/sagernet/sing-shadowsocks2 v0.2.0 // indirect - github.com/sagernet/sing-shadowtls v0.1.4 // indirect - github.com/sagernet/sing-tun v0.3.3 // indirect - github.com/sagernet/sing-vmess v0.1.12 // 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-20231215174105-89dec3b2f3e8 // indirect + github.com/sagernet/gvisor v0.0.0-20250909151924-850a370d8506 // indirect + github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect + github.com/sagernet/quic-go v0.55.0-sing-box-mod.2 // indirect + github.com/sagernet/sing-mux v0.3.3 // indirect + github.com/sagernet/sing-quic v0.6.0-beta.4 // indirect + github.com/sagernet/sing-shadowsocks v0.2.8 // indirect + github.com/sagernet/sing-shadowsocks2 v0.2.1 // indirect + github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 // indirect + github.com/sagernet/sing-tun v0.8.0-beta.11 // indirect + github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 // indirect + github.com/sagernet/smux v1.5.34-mod.2 // indirect + github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20250917110311-16510ac47288 // indirect github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // indirect - github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect - github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect - github.com/vishvananda/netns v0.0.4 // indirect - github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d // indirect - github.com/xtls/xray-core v1.8.21 // indirect - github.com/zeebo/blake3 v0.2.3 // indirect - go.uber.org/mock v0.4.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect + github.com/vishvananda/netns v0.0.5 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.28.0 - golang.org/x/sync v0.8.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - lukechampine.com/blake3 v1.3.0 // indirect + golang.org/x/crypto v0.43.0 // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.46.0 + golang.org/x/sync v0.17.0 // indirect + golang.org/x/text v0.30.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/tools v0.37.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect + lukechampine.com/blake3 v1.4.0 // indirect ) -replace github.com/sagernet/sing-box => github.com/hiddify/hiddify-sing-box v1.8.9-0.20240928213625-7b79bf0c814d - -replace github.com/xtls/xray-core => github.com/hiddify/xray-core v0.0.0-20240902024714-0fcb0895bb4b - replace github.com/sagernet/wireguard-go => github.com/hiddify/wireguard-go v0.0.0-20240727191222-383c1da14ff1 - -replace github.com/bepass-org/warp-plus => github.com/hiddify/warp-plus v0.0.0-20240717223357-4f3122e0d11d - -replace github.com/hiddify/ray2sing => github.com/hiddify/ray2sing v0.0.0-20240928221833-190b549d5222 diff --git a/go.sum b/go.sum index 3f2f2606..1dd6cc90 100644 --- a/go.sum +++ b/go.sum @@ -1,40 +1,36 @@ -berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw= -berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 h1:Wo41lDOevRJSGpevP+8Pk5bANX7fJacO2w04aqLiC5I= -github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Yiwen-Chan/tinydb v0.0.0-20230129042445-3321642f0674 h1:Sf029Pn6NCxD0TP/AeEO87epoaNeCtUFrCHKndEc3G0= -github.com/Yiwen-Chan/tinydb v0.0.0-20230129042445-3321642f0674/go.mod h1:FKpvt4bXlMiJn5DipBosCuM1tH27p0z9RI3sHRMH+40= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= +github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= +github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/anthropics/anthropic-sdk-go v1.14.0 h1:EzNQvnZlaDHe2UPkoUySDz3ixRgNbwKdH8KtFpv7pi4= +github.com/anthropics/anthropic-sdk-go v1.14.0/go.mod h1:WTz31rIUHUHqai2UslPpw5CwXrQP3geYBioRV4WOLvE= +github.com/anytls/sing-anytls v0.0.11 h1:w8e9Uj1oP3m4zxkyZDewPk0EcQbvVxb7Nn+rapEx4fc= +github.com/anytls/sing-anytls v0.0.11/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -51,43 +47,53 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc= -github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg= +github.com/caddyserver/certmagic v0.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU= +github.com/caddyserver/certmagic v0.23.0/go.mod h1:9mEZIWqqWoI+Gf+4Trh04MOVPD0tGSxtqsxg87hAIH4= +github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= +github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk= +github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY= -github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= +github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0= +github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo= github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI= +github.com/database64128/netx-go v0.1.1 h1:dT5LG7Gs7zFZBthFBbzWE6K8wAHjSNAaK7wCYZT7NzM= +github.com/database64128/netx-go v0.1.1/go.mod h1:LNlYVipaYkQArRFDNNJ02VkNV+My9A5XR/IGS7sIBQc= +github.com/database64128/tfo-go/v2 v2.3.1 h1:EGE+ELd5/AQ0X6YBlQ9RgKs8+kciNhgN3d8lRvfEJQw= +github.com/database64128/tfo-go/v2 v2.3.1/go.mod h1:k9wcpg/8i5zenspBkc9jUEYehpZZccBnCElzOJB++bU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa h1:h8TfIT1xc8FWbwwpmHn1J5i43Y0uZP97GqasGCzSRJk= +github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa/go.mod h1:Nx87SkVqTKd8UtT+xu7sM/l+LgXs6c0aHrlKusR+2EQ= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= @@ -97,9 +103,8 @@ github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KP github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= -github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= -github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e h1:vUmf0yezR0y7jJ5pceLHthLaYf4bA5T14B6q39S4q2Q= +github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e/go.mod h1:YTIHhz/QFSYnu/EhlF2SpU2Uk+32abacUYA5ZPljz1A= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -119,43 +124,42 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqL github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk= -github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/gaissmai/bart v0.18.0 h1:jQLBT/RduJu0pv/tLwXE+xKPgtWJejbxuXAR+wLJafo= +github.com/gaissmai/bart v0.18.0/go.mod h1:JJzMAhNF5Rjo4SF4jWBrANuJfqY+FvsFhW7t1UZJ+XY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4= -github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= -github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= -github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= +github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= +github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= +github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= +github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -167,8 +171,6 @@ github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= @@ -177,8 +179,14 @@ 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.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -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/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= +github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= +github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0= +github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -186,11 +194,9 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U= -github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -207,30 +213,27 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g= -github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 h1:wG8RYIyctLhdFk6Vl1yPGtSRtwGpVkWyZww1OCil2MI= +github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -239,11 +242,9 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -266,45 +267,35 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= -github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= +github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/hiddify/hiddify-app-demo-extension v0.0.0-20241001070003-26039f960ad6 h1:ZErxaLRV5iWCBAR8qsyoNemEKntE4WSvK00Ts4zbS84= github.com/hiddify/hiddify-app-demo-extension v0.0.0-20241001070003-26039f960ad6/go.mod h1:1F56GeIkSjUJF0VP/zPS9rJhVc97TjEQsDTFhmr9Ddc= -github.com/hiddify/hiddify-ip-scanner-extension v0.0.0-20241001070353-7ffd688b96b2 h1:cEzfvap7MfInrl15PWkt7761D/hc7JYVwFLIek3CGm8= -github.com/hiddify/hiddify-ip-scanner-extension v0.0.0-20241001070353-7ffd688b96b2/go.mod h1:/jZoGToOSqviabjNGrwRA5UsiO6EggHsRDaMK3sCHw8= -github.com/hiddify/hiddify-sing-box v1.8.9-0.20240928213625-7b79bf0c814d h1:+jTGlmOl+Kt3JEU1pt5yIItpi6nKKqUIUf76jkONHgQ= -github.com/hiddify/hiddify-sing-box v1.8.9-0.20240928213625-7b79bf0c814d/go.mod h1:2Cozqb5uVY/y0c/HWZ57CfE6fZwjmik/J3tWynsjjDA= -github.com/hiddify/ray2sing v0.0.0-20240928221833-190b549d5222 h1:+MFxFxoWCA44WhqIixqL/Zkt4DwnqhQvafS0Dm4+dKM= -github.com/hiddify/ray2sing v0.0.0-20240928221833-190b549d5222/go.mod h1:cFEg1b0eBgL9kBgIPAD71lHO1Q5g20PZL4dUGhQpAO8= -github.com/hiddify/warp-plus v0.0.0-20240717223357-4f3122e0d11d h1:vRGKh9ou+/vQGfVYa8MczhbIVjHxlP52OWwrDWO77RA= -github.com/hiddify/warp-plus v0.0.0-20240717223357-4f3122e0d11d/go.mod h1:uSRUbr1CcvFrEV69FTvuJFwpzEmwO8N4knb6+Zq3Ys4= github.com/hiddify/wireguard-go v0.0.0-20240727191222-383c1da14ff1 h1:xdbHlZtzs+jijAxy85qal835GglwmjohA/srHT8gm9s= github.com/hiddify/wireguard-go v0.0.0-20240727191222-383c1da14ff1/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc= -github.com/hiddify/xray-core v0.0.0-20240902024714-0fcb0895bb4b h1:fF9wb8XnL4dk/suRK1cOKPN1x1BG3F5iHN3Aq2mrKaE= -github.com/hiddify/xray-core v0.0.0-20240902024714-0fcb0895bb4b/go.mod h1:kYMVgEAXeeoD9I08aS15jLRv4RF88vc1uf8xIjlnskU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/imkira/go-observer/v2 v2.0.0-20230629064422-8e0b61f11f1b h1:1+115FqGoS8p6Iry9AYmrcWDvSveH0F7P2nX1LU00qg= -github.com/imkira/go-observer/v2 v2.0.0-20230629064422-8e0b61f11f1b/go.mod h1:XCscqBi1KKh7GcVDDAdkT/Cf6WDjnDAA1XM3nwmA0Ag= +github.com/illarion/gonotify/v3 v3.0.2 h1:O7S6vcopHexutmpObkeWsnzMJt/r1hONIEogeVNmJMk= +github.com/illarion/gonotify/v3 v3.0.2/go.mod h1:HWGPdPe817GfvY3w7cx6zkbzNZfi3QjcBm/wgVvEL1U= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA= -github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f h1:dd33oobuIv9PcBVqvbEiCXEbNTomOHyj3WFuC5YiPRU= +github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f/go.mod h1:zhFlBeJssZ1YBCMZ5Lzu1pX4vhftDvU10WUVb1uXKtM= github.com/jellydator/validation v1.1.0 h1:TBkx56y6dd0By2AhtStRdTIhDjtcuoSE9w6G6z7wQ4o= github.com/jellydator/validation v1.1.0/go.mod h1:AaCjfkQ4Ykdcb+YCwqCtaI3wDsf2UAGhJ06lJs0VgOw= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= -github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= -github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I= +github.com/jsimonetti/rtnetlink v1.4.0/go.mod h1:5W1jDvWdnthFJ7fxYX1GMK07BUpI4oskfOqvPteYS6E= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -312,50 +303,46 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60= github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= +github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= +github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/libdns/alidns v1.0.3 h1:LFHuGnbseq5+HCeGa1aW8awyX/4M2psB9962fdD2+yQ= -github.com/libdns/alidns v1.0.3/go.mod h1:e18uAG6GanfRhcJj6/tps2rCMzQJaYVcGKT+ELjdjGE= -github.com/libdns/cloudflare v0.1.1 h1:FVPfWwP8zZCqj268LZjmkDleXlHPlFU9KC4OJ3yn054= -github.com/libdns/cloudflare v0.1.1/go.mod h1:9VK91idpOjg6v7/WbjkEW49bSCxj00ALesIFDhJ8PBU= -github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= -github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= -github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= +github.com/libdns/alidns v1.0.5-libdns.v1.beta1 h1:txHK7UxDed3WFBDjrTZPuMn8X+WmhjBTTAMW5xdy5pQ= +github.com/libdns/alidns v1.0.5-libdns.v1.beta1/go.mod h1:ystHmPwcGoWjPrGpensQSMY9VoCx4cpR2hXNlwk9H/g= +github.com/libdns/cloudflare v0.2.2-0.20250708034226-c574dccb31a6 h1:3MGrVWs2COjMkQR17oUw1zMIPbm2YAzxDC3oGVZvQs8= +github.com/libdns/cloudflare v0.2.2-0.20250708034226-c574dccb31a6/go.mod h1:w9uTmRCDlAoafAsTPnn2nJ0XHK/eaUMh86DUk8BWi60= +github.com/libdns/libdns v1.0.0-beta.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= +github.com/libdns/libdns v1.1.0 h1:9ze/tWvt7Df6sbhOJRB8jT33GHEHpEQXdtkE3hPthbU= +github.com/libdns/libdns v1.1.0/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -366,20 +353,27 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d h1:j9LtzkYstLFoNvXW824QQeN7Y26uPL5249kzWKbzO9U= -github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts= -github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30= -github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= +github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= +github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 h1:A1Cq6Ysb0GM0tpKMbdCXCIfBclan4oHk1Jb+Hrejirg= +github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42/go.mod h1:BB4YCPDOzfy7FniQ/lxuYQ3dgmM2cZumHbK8RpTjN2o= +github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ3c= +github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE= +github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= +github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= +github.com/metacubex/utls v1.8.3 h1:0m/yCxm3SK6kWve2lKiFb1pue1wHitJ8sQQD4Ikqde4= +github.com/metacubex/utls v1.8.3/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= +github.com/mholt/acmez/v3 v3.1.2 h1:auob8J/0FhmdClQicvJvuDavgd5ezwLBfKuYmynhYzc= +github.com/mholt/acmez/v3 v3.1.2/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= -github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= +github.com/miekg/dns v1.1.67 h1:kg0EHj0G4bfT5/oOys6HhZw4vmMlnoZ+gDu8tJ/AlI0= +github.com/miekg/dns v1.1.67/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= @@ -402,8 +396,8 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= -github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -414,64 +408,40 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/ooni/go-libtor v1.1.8 h1:Wo3V3DVTxl5vZdxtQakqYP+DAHx7pPtAFSl1bnAa08w= -github.com/ooni/go-libtor v1.1.8/go.mod h1:q1YyLwRD9GeMyeerVvwc0vJ2YgwDLTp2bdVcrh/JXyI= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs= -github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= -github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= -github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= -github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= -github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= -github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= -github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/transport/v2 v2.2.3 h1:XcOE3/x41HOSKbl1BfyY1TF1dERx7lVvlMCbXU7kfvA= -github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= -github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/turn/v3 v3.0.1 h1:wLi7BTQr6/Q20R0vt/lHbjv6y4GChFtC33nkYbasoT8= -github.com/pion/turn/v3 v3.0.1/go.mod h1:MrJDKgqryDyWy1/4NT9TWfXWGMC7UHT6pJIv1+gMeNE= -github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= -github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4= +github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -483,111 +453,76 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= -github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM= -github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0= -github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= -github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rodaine/table v1.1.1 h1:zBliy3b4Oj6JRmncse2Z85WmoQvDrXOYuy0JXCt8Qz8= -github.com/rodaine/table v1.1.1/go.mod h1:iqTRptjn+EVcrVBYtNMlJ2wrJZa3MpULUmcXFpfcziA= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= +github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkkD2QgdTuzQG263YZ+2emfpeyGqW0= github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM= -github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 h1:YbmpqPQEMdlk9oFSKYWRqVuu9qzNiOayIonKmv1gCXY= -github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1/go.mod h1:J2yAxTFPDjrDPhuAi9aWFz2L3ox9it4qAluBBbN0H5k= -github.com/sagernet/gomobile v0.1.4 h1:WzX9ka+iHdupMgy2Vdich+OAt7TM8C2cZbIbzNjBrJY= -github.com/sagernet/gomobile v0.1.4/go.mod h1:Pqq2+ZVvs10U7xK+UwJgwYWUykewi8H6vlslAO73n9E= -github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I= -github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0= -github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba h1:EY5AS7CCtfmARNv2zXUOrsEMPFDGYxaw65JzA2p51Vk= -github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= -github.com/sagernet/quic-go v0.47.0-beta.2 h1:1tCGWFOSaXIeuQaHrwOMJIYvlupjTcaVInGQw5ArULU= -github.com/sagernet/quic-go v0.47.0-beta.2/go.mod h1:bLVKvElSEMNv7pu7SZHscW02TYigzQ5lQu3Nh4wNh8Q= -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.3 h1:Ty/NAiNnVd6844k7ujlL5lkzydhcTH5Psc432jXA4Y8= -github.com/sagernet/sing v0.4.3/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls= -github.com/sagernet/sing-dns v0.2.3 h1:YzeBUn2tR38F7HtvGEQ0kLRLmZWMEgi/+7wqa4Twb1k= -github.com/sagernet/sing-dns v0.2.3/go.mod h1:BJpJv6XLnrUbSyIntOT6DG9FW0f4fETmPAHvNjOprLg= -github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo= -github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ= -github.com/sagernet/sing-quic v0.2.2 h1:Ryp02zMhHh/ZDrG7MdLsmhuBU8+BEpOdJonFQiqIopo= -github.com/sagernet/sing-quic v0.2.2/go.mod h1:YLV1dUDv8Eyp/8e55O/EvfsrwxOgEDVgDCIoPqmDREE= -github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= -github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= -github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg= -github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= -github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= -github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= -github.com/sagernet/sing-tun v0.3.3 h1:LZnQNmfGcNG2KPTPkLgc+Lo7k606QJVkPp2DnjriwUk= -github.com/sagernet/sing-tun v0.3.3/go.mod h1:DxLIyhjWU/HwGYoX0vNGg2c5QgTQIakphU1MuERR5tQ= -github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg= -github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I= -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/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ= +github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI= +github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs= +github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o= +github.com/sagernet/gomobile v0.1.8 h1:vXgoN0pjsMONAaYCTdsKBX2T1kxuS7sbT/mZ7PElGoo= +github.com/sagernet/gomobile v0.1.8/go.mod h1:A8l3FlHi2D/+mfcd4HHvk5DGFPW/ShFb9jHP5VmSiDY= +github.com/sagernet/gvisor v0.0.0-20250909151924-850a370d8506 h1:x/t3XqWshOlWqRuumpvbUvjtEr/6mJuBXAVovPefbUg= +github.com/sagernet/gvisor v0.0.0-20250909151924-850a370d8506/go.mod h1:QkkPEJLw59/tfxgapHta14UL5qMUah5NXhO0Kw2Kan4= +github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis= +github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= +github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I= +github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= +github.com/sagernet/quic-go v0.55.0-sing-box-mod.2 h1:I79gW4Xl5ciVARHfnp122lDAMhC0AwUCU765Q8Kxdfo= +github.com/sagernet/quic-go v0.55.0-sing-box-mod.2/go.mod h1:IE9naq7Kekj0rPAdWc0GLW1ENR7gAOQV9VRTDlKN8Bk= +github.com/sagernet/sing v0.6.9/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.8.0-beta.6 h1:GXv1j1xWHihx6ptyOXh0yp4jUqJoNjCqD8d+AI9rnLU= +github.com/sagernet/sing v0.8.0-beta.6/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing-box v1.13.0-alpha.27 h1:B9Y4oW/nbrF3v84GiAFjSUDvm/tqoO1NsDIEjP32w1c= +github.com/sagernet/sing-box v1.13.0-alpha.27/go.mod h1:bV27uL6xQ0laIDvcvsq6My+Bw/XA18bOwCU2Dzf62es= +github.com/sagernet/sing-dns v0.4.6 h1:mjZC0o6d5sQ1sraoOBbK3G3apCbuL8wWYwu2RNu5rbM= +github.com/sagernet/sing-dns v0.4.6/go.mod h1:dweQs54ng2YGzoJfz+F9dGuDNdP5pJ3PLeggnK5VWc8= +github.com/sagernet/sing-mux v0.3.3 h1:YFgt9plMWzH994BMZLmyKL37PdIVaIilwP0Jg+EcLfw= +github.com/sagernet/sing-mux v0.3.3/go.mod h1:pht8iFY4c9Xltj7rhVd208npkNaeCxzyXCgulDPLUDA= +github.com/sagernet/sing-quic v0.6.0-beta.4 h1:2k/+Xrv/pjl7AYC7LD9tcB7y1lIgw04LjJjqTI8q5Xk= +github.com/sagernet/sing-quic v0.6.0-beta.4/go.mod h1:FNvKPADzMZprwm7UQCcCGPhYifpb5rxoCOntOupJU+8= +github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE= +github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI= +github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo= +github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= +github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w= +github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= +github.com/sagernet/sing-tun v0.8.0-beta.11 h1:xVi8VcVkvz2o+3v1PLv5MOkFpiVCwjLjucVlmigDi5c= +github.com/sagernet/sing-tun v0.8.0-beta.11/go.mod h1:eWETzl4AwaxGKiZTpDIDVJLTBz9cfIdoZwaZY1jlSjg= +github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o= +github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY= +github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4= +github.com/sagernet/smux v1.5.34-mod.2/go.mod h1:0KW0+R+ycvA2INW4gbsd7BNyg+HEfLIAxa5N02/28Zc= +github.com/sagernet/tailscale v1.86.5-sing-box-1.13-mod.4 h1:Ceg+9Ug+qAFgEchGodlHmMOY2h7KktQQDAyuoIsPbos= +github.com/sagernet/tailscale v1.86.5-sing-box-1.13-mod.4/go.mod h1:YdN/avjce8sqPFLT9E1uEh8gPewNSnC41U4ZhBJ+ACw= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4= -github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -596,8 +531,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -605,13 +538,14 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -620,25 +554,52 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ= +github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4= +github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4= +github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= +github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPxRs2O36yuGRW3f9SYV+bMTTvMBI0EKio= +github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= +github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw= +github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8= +github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= +github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= +github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+yfntqhI3oAu9i27nEojcQ4NuBQOo5ZFA= +github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc/go.mod h1:f93CXfllFsO9ZQVq+Zocb1Gp4G5Fz0b0rXHLOzt/Djc= +github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:UBPHPtv8+nEAy2PD8RyAhOYvau1ek0HDJqLS/Pysi14= +github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= +github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da h1:jVRUZPRs9sqyKlYHHzHjAqKN+6e/Vog6NpHYeNPJqOw= +github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4= +github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= +github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA= -github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264= +github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM= +github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -646,40 +607,45 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI= -github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= -github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xmdhs/clash2singbox v0.0.2 h1:/gxaFm8fmv+UcUZzK508Z0yR01wg1LHrrq872Qibk1I= -github.com/xmdhs/clash2singbox v0.0.2/go.mod h1:B5pbJCwIHhJg6YRPCT04EXw6XXNIIOllMfL3XyJ7ob8= +github.com/xmdhs/clash2singbox v0.1.4 h1:fhyFLve8VR/FtNVTjBLDsxRkzWqhUpaXq4XDdGYqWXM= +github.com/xmdhs/clash2singbox v0.1.4/go.mod h1:u2kIEBN2r26EGFSdU7mTwCqz4XG2B7Cwq8U1dVn2IXI= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg= -github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -689,35 +655,32 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= +go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= +go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4hOxG5YpKCzkek= +go4.org/mem v0.0.0-20240501181205-ae6ca9944745/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= -golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= +golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -727,16 +690,12 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -744,7 +703,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -757,42 +715,30 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -807,59 +753,41 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.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.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= +golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -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/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -869,30 +797,25 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= +golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= +golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= +golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= @@ -900,10 +823,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -917,8 +838,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= -google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= +google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -929,8 +850,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -941,7 +862,6 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -956,21 +876,20 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 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.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 h1:2gap+Kh/3F47cO6hAu3idFvsJ0ue6TRcEi2IUkv/F8k= +gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= -lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w= +lukechampine.com/blake3 v1.4.0/go.mod h1:MQJNQCTnR+kwOP/JEZSxj3MaQjp80FOFSNMMHXcSeX0= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= +software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/hiddify-core.tar.gz b/hiddify-core.tar.gz deleted file mode 100644 index 7ca4eaa3..00000000 Binary files a/hiddify-core.tar.gz and /dev/null differ diff --git a/mobile/mobile.go b/mobile/mobile.go index 3eefeb1c..6157f37d 100644 --- a/mobile/mobile.go +++ b/mobile/mobile.go @@ -1,7 +1,7 @@ package mobile import ( - "encoding/json" + json "github.com/goccy/go-json" "os" "path/filepath" @@ -19,29 +19,29 @@ func Setup(baseDir string, workingDir string, tempDir string, debug bool) error } func Parse(path string, tempPath string, debug bool) error { - config, err := config.ParseConfig(tempPath, debug) - if err != nil { - return err - } - return os.WriteFile(path, config, 0o644) + config, err := config.ParseConfig(tempPath, debug) + if err != nil { + return err + } + return os.WriteFile(path, config, 0o644) } func BuildConfig(path string, HiddifyOptionsJson string) (string, error) { - os.Chdir(filepath.Dir(path)) - fileContent, err := os.ReadFile(path) - if err != nil { - return "", err - } - var options option.Options - err = options.UnmarshalJSON(fileContent) - if err != nil { - return "", err - } - HiddifyOptions := &config.HiddifyOptions{} - err = json.Unmarshal([]byte(HiddifyOptionsJson), HiddifyOptions) - if err != nil { - return "", nil - } + os.Chdir(filepath.Dir(path)) + fileContent, err := os.ReadFile(path) + if err != nil { + return "", err + } + var options option.Options + err = json.Unmarshal(fileContent, &options) + if err != nil { + return "", err + } + HiddifyOptions := &config.HiddifyOptions{} + err = json.Unmarshal([]byte(HiddifyOptionsJson), HiddifyOptions) + if err != nil { + return "", err + } if HiddifyOptions.Warp.WireguardConfigStr != "" { err := json.Unmarshal([]byte(HiddifyOptions.Warp.WireguardConfigStr), &HiddifyOptions.Warp.WireguardConfig) if err != nil { diff --git a/build_windows.bat b/scripts/build_windows.bat similarity index 100% rename from build_windows.bat rename to scripts/build_windows.bat diff --git a/cmd.bat b/scripts/cmd.bat similarity index 100% rename from cmd.bat rename to scripts/cmd.bat diff --git a/cmd.sh b/scripts/cmd.sh old mode 100755 new mode 100644 similarity index 100% rename from cmd.sh rename to scripts/cmd.sh diff --git a/v2/command_client.go b/v2/command_client.go index 6e3ca021..cb924863 100644 --- a/v2/command_client.go +++ b/v2/command_client.go @@ -1,77 +1,86 @@ package v2 import ( - pb "github.com/hiddify/hiddify-core/hiddifyrpc" - "github.com/sagernet/sing-box/experimental/libbox" - "github.com/sagernet/sing-box/log" + pb "github.com/hiddify/hiddify-core/hiddifyrpc" + "github.com/sagernet/sing-box/experimental/libbox" + "github.com/sagernet/sing-box/log" ) type CommandClientHandler struct { - port int64 - logger log.Logger + port int64 + logger log.Logger } func (cch *CommandClientHandler) Connected() { - cch.logger.Debug("CONNECTED") + if cch.logger != nil { cch.logger.Debug("CONNECTED") } } -func (cch *CommandClientHandler) Disconnected(message string) { - cch.logger.Debug("DISCONNECTED: ", message) +// Legacy methods (older libbox) +func (cch *CommandClientHandler) ClearLog() { if cch.logger != nil { cch.logger.Debug("clear log") } } +func (cch *CommandClientHandler) WriteLog(message string) { if cch.logger != nil { cch.logger.Debug("log:", message) } } + +// New methods in libbox v1.13 +func (cch *CommandClientHandler) ClearLogs() { if cch.logger != nil { cch.logger.Debug("clear logs") } } +func (cch *CommandClientHandler) WriteLogs(messageList libbox.StringIterator) { + for messageList.HasNext() { + msg := messageList.Next() + if cch.logger != nil { cch.logger.Debug("log:", msg) } + } } -func (cch *CommandClientHandler) ClearLog() { - cch.logger.Debug("clear log") +func (cch *CommandClientHandler) Disconnected(message string) { + if cch.logger != nil { cch.logger.Debug("DISCONNECTED: ", message) } } -func (cch *CommandClientHandler) WriteLog(message string) { - cch.logger.Debug("log: ", message) +func (cch *CommandClientHandler) WriteConnections(message *libbox.Connections) { + if cch.logger != nil { cch.logger.Debug("connections update") } } func (cch *CommandClientHandler) WriteStatus(message *libbox.StatusMessage) { - systemInfoObserver.Emit(pb.SystemInfo{ - ConnectionsIn: message.ConnectionsIn, - ConnectionsOut: message.ConnectionsOut, - Uplink: message.Uplink, - Downlink: message.Downlink, - UplinkTotal: message.UplinkTotal, - DownlinkTotal: message.DownlinkTotal, - Memory: message.Memory, - Goroutines: message.Goroutines, - }) - cch.logger.Debug("Memory: ", libbox.FormatBytes(message.Memory), ", Goroutines: ", message.Goroutines) - + systemInfoObserver.Emit(&pb.SystemInfo{ + ConnectionsIn: message.ConnectionsIn, + ConnectionsOut: message.ConnectionsOut, + Uplink: message.Uplink, + Downlink: message.Downlink, + UplinkTotal: message.UplinkTotal, + DownlinkTotal: message.DownlinkTotal, + Memory: message.Memory, + }) + if cch.logger != nil { cch.logger.Debug("Memory: ", libbox.FormatBytes(message.Memory), ", Goroutines: ", message.Goroutines) } } func (cch *CommandClientHandler) WriteGroups(message libbox.OutboundGroupIterator) { - if message == nil { - return - } - groups := pb.OutboundGroupList{} - for message.HasNext() { - group := message.Next() - items := group.GetItems() - groupItems := []*pb.OutboundGroupItem{} - for items.HasNext() { - item := items.Next() - groupItems = append(groupItems, - &pb.OutboundGroupItem{ - Tag: item.Tag, - Type: item.Type, - UrlTestTime: item.URLTestTime, - UrlTestDelay: item.URLTestDelay, - }, - ) - } - groups.Items = append(groups.Items, &pb.OutboundGroup{Tag: group.Tag, Type: group.Type, Selected: group.Selected, Items: groupItems}) - } - outboundsInfoObserver.Emit(groups) - mainOutboundsInfoObserver.Emit(groups) + if message == nil { + return + } + groups := &pb.OutboundGroupList{} + for message.HasNext() { + group := message.Next() + items := group.GetItems() + groupItems := []*pb.OutboundGroupItem{} + for items.HasNext() { + item := items.Next() + groupItems = append(groupItems, &pb.OutboundGroupItem{ + Tag: item.Tag, + Type: item.Type, + UrlTestTime: item.URLTestTime, + UrlTestDelay: item.URLTestDelay, + }) + } + groups.Items = append(groups.Items, &pb.OutboundGroup{ + Tag: group.Tag, + Type: group.Type, + Selected: group.Selected, + Items: groupItems, + }) + } + outboundsInfoObserver.Emit(groups) + mainOutboundsInfoObserver.Emit(groups) } func (cch *CommandClientHandler) InitializeClashMode(modeList libbox.StringIterator, currentMode string) { - cch.logger.Debug("initial clash mode: ", currentMode) + if cch.logger != nil { cch.logger.Debug("initial clash mode: ", currentMode) } } - func (cch *CommandClientHandler) UpdateClashMode(newMode string) { - cch.logger.Debug("update clash mode: ", newMode) + if cch.logger != nil { cch.logger.Debug("update clash mode: ", newMode) } } diff --git a/v2/commands.go b/v2/commands.go index effe5d86..942cf8fd 100644 --- a/v2/commands.go +++ b/v2/commands.go @@ -1,156 +1,4 @@ -package v2 - -import ( - "context" - "time" - - pb "github.com/hiddify/hiddify-core/hiddifyrpc" - "github.com/sagernet/sing-box/experimental/libbox" - "google.golang.org/grpc" -) - -var ( - systemInfoObserver = NewObserver[pb.SystemInfo](10) - outboundsInfoObserver = NewObserver[pb.OutboundGroupList](10) - mainOutboundsInfoObserver = NewObserver[pb.OutboundGroupList](10) -) - -var ( - statusClient *libbox.CommandClient - groupClient *libbox.CommandClient - groupInfoOnlyClient *libbox.CommandClient -) - -func (s *CoreService) GetSystemInfo(req *pb.Empty, stream grpc.ServerStreamingServer[pb.SystemInfo]) error { - if statusClient == nil { - statusClient = libbox.NewCommandClient( - &CommandClientHandler{}, - &libbox.CommandClientOptions{ - Command: libbox.CommandStatus, - StatusInterval: 1000000000, // 1000ms debounce - }, - ) - - defer func() { - statusClient.Disconnect() - statusClient = nil - }() - statusClient.Connect() - } - - sub, done, _ := systemInfoObserver.Subscribe() - - for { - select { - case <-stream.Context().Done(): - return nil - case <-done: - return nil - case info := <-sub: - stream.Send(&info) - case <-time.After(1000 * time.Millisecond): - } - } -} - -func (s *CoreService) OutboundsInfo(req *pb.Empty, stream grpc.ServerStreamingServer[pb.OutboundGroupList]) error { - if groupClient == nil { - groupClient = libbox.NewCommandClient( - &CommandClientHandler{}, - &libbox.CommandClientOptions{ - Command: libbox.CommandGroup, - StatusInterval: 500000000, // 500ms debounce - }, - ) - - defer func() { - groupClient.Disconnect() - groupClient = nil - }() - groupClient.Connect() - } - - sub, done, _ := outboundsInfoObserver.Subscribe() - - for { - select { - case <-stream.Context().Done(): - return nil - case <-done: - return nil - case info := <-sub: - stream.Send(&info) - case <-time.After(500 * time.Millisecond): - } - } -} - -func (s *CoreService) MainOutboundsInfo(req *pb.Empty, stream grpc.ServerStreamingServer[pb.OutboundGroupList]) error { - if groupInfoOnlyClient == nil { - groupInfoOnlyClient = libbox.NewCommandClient( - &CommandClientHandler{}, - &libbox.CommandClientOptions{ - Command: libbox.CommandGroupInfoOnly, - StatusInterval: 500000000, // 500ms debounce - }, - ) - - defer func() { - groupInfoOnlyClient.Disconnect() - groupInfoOnlyClient = nil - }() - groupInfoOnlyClient.Connect() - } - - sub, stopch, _ := mainOutboundsInfoObserver.Subscribe() - - for { - select { - case <-stream.Context().Done(): - return nil - case <-stopch: - return nil - case info := <-sub: - stream.Send(&info) - case <-time.After(500 * time.Millisecond): - } - } -} - -func (s *CoreService) SelectOutbound(ctx context.Context, in *pb.SelectOutboundRequest) (*pb.Response, error) { - return SelectOutbound(in) -} - -func SelectOutbound(in *pb.SelectOutboundRequest) (*pb.Response, error) { - err := libbox.NewStandaloneCommandClient().SelectOutbound(in.GroupTag, in.OutboundTag) - if err != nil { - return &pb.Response{ - ResponseCode: pb.ResponseCode_FAILED, - Message: err.Error(), - }, err - } - - return &pb.Response{ - ResponseCode: pb.ResponseCode_OK, - Message: "", - }, nil -} - -func (s *CoreService) UrlTest(ctx context.Context, in *pb.UrlTestRequest) (*pb.Response, error) { - return UrlTest(in) -} - -func UrlTest(in *pb.UrlTestRequest) (*pb.Response, error) { - err := libbox.NewStandaloneCommandClient().URLTest(in.GroupTag) - if err != nil { - return &pb.Response{ - ResponseCode: pb.ResponseCode_FAILED, - Message: err.Error(), - }, err - } - - return &pb.Response{ - ResponseCode: pb.ResponseCode_OK, - Message: "", - }, nil -} +//go:build ignore +// +build ignore + +package v2 diff --git a/v2/commands_v113.go b/v2/commands_v113.go new file mode 100644 index 00000000..b2f319cd --- /dev/null +++ b/v2/commands_v113.go @@ -0,0 +1,117 @@ +package v2 + +import ( + "time" + + pb "github.com/hiddify/hiddify-core/hiddifyrpc" + "github.com/sagernet/sing-box/experimental/libbox" + "google.golang.org/grpc" +) + +var ( + statusClient *libbox.CommandClient + groupClient *libbox.CommandClient + groupInfoOnlyClient *libbox.CommandClient +) + +func (s *CoreService) GetSystemInfo(req *pb.Empty, stream grpc.ServerStreamingServer[pb.SystemInfo]) error { + if statusClient == nil { + statusClient = libbox.NewCommandClient( + &CommandClientHandler{}, + &libbox.CommandClientOptions{ + Command: libbox.CommandStatus, + StatusInterval: 1_000_000_000, // 1000ms debounce + }, + ) + defer func() { + statusClient.Disconnect() + statusClient = nil + }() + statusClient.Connect() + } + + sub, done, _ := systemInfoObserver.Subscribe() + defer systemInfoObserver.UnSubscribe(sub) + + for { + select { + case <-stream.Context().Done(): + return nil + case <-done: + return nil + case info := <-sub: + if err := stream.Send(info); err != nil { + return err + } + case <-time.After(1 * time.Second): + } + } +} + +func (s *CoreService) OutboundsInfo(req *pb.Empty, stream grpc.ServerStreamingServer[pb.OutboundGroupList]) error { + if groupClient == nil { + groupClient = libbox.NewCommandClient( + &CommandClientHandler{}, + &libbox.CommandClientOptions{ + Command: libbox.CommandGroup, + StatusInterval: 500_000_000, // 500ms debounce + }, + ) + defer func() { + groupClient.Disconnect() + groupClient = nil + }() + groupClient.Connect() + } + + sub, done, _ := outboundsInfoObserver.Subscribe() + defer outboundsInfoObserver.UnSubscribe(sub) + + for { + select { + case <-stream.Context().Done(): + return nil + case <-done: + return nil + case info := <-sub: + if err := stream.Send(info); err != nil { + return err + } + case <-time.After(500 * time.Millisecond): + } + } +} + +func (s *CoreService) MainOutboundsInfo(req *pb.Empty, stream grpc.ServerStreamingServer[pb.OutboundGroupList]) error { + if groupInfoOnlyClient == nil { + groupInfoOnlyClient = libbox.NewCommandClient( + &CommandClientHandler{}, + &libbox.CommandClientOptions{ + Command: libbox.CommandGroup, + StatusInterval: 500_000_000, // 500ms debounce + }, + ) + defer func() { + groupInfoOnlyClient.Disconnect() + groupInfoOnlyClient = nil + }() + groupInfoOnlyClient.Connect() + } + + sub, stopch, _ := mainOutboundsInfoObserver.Subscribe() + defer mainOutboundsInfoObserver.UnSubscribe(sub) + + for { + select { + case <-stream.Context().Done(): + return nil + case <-stopch: + return nil + case info := <-sub: + if err := stream.Send(info); err != nil { + return err + } + case <-time.After(500 * time.Millisecond): + } + } +} diff --git a/v2/coreinfo.go b/v2/coreinfo.go index 4703f48e..5840797a 100644 --- a/v2/coreinfo.go +++ b/v2/coreinfo.go @@ -1,7 +1,7 @@ package v2 import ( - "encoding/json" + json "github.com/goccy/go-json" "fmt" "github.com/hiddify/hiddify-core/bridge" diff --git a/v2/custom.go b/v2/custom.go index 7bde2ef8..00290058 100644 --- a/v2/custom.go +++ b/v2/custom.go @@ -2,7 +2,7 @@ package v2 import ( "context" - "encoding/json" + json "github.com/goccy/go-json" "fmt" "os" "path/filepath" @@ -209,18 +209,18 @@ func ChangeHiddifySettings(in *pb.ChangeHiddifySettingsRequest) (*pb.CoreInfoRes if err != nil { return nil, err } - if HiddifyOptions.Warp.WireguardConfigStr != "" { - err := json.Unmarshal([]byte(HiddifyOptions.Warp.WireguardConfigStr), &HiddifyOptions.Warp.WireguardConfig) - if err != nil { - return nil, err - } - } - if HiddifyOptions.Warp2.WireguardConfigStr != "" { - err := json.Unmarshal([]byte(HiddifyOptions.Warp2.WireguardConfigStr), &HiddifyOptions.Warp2.WireguardConfig) - if err != nil { - return nil, err - } - } + // if HiddifyOptions.Warp.WireguardConfigStr != "" { + // err := json.Unmarshal([]byte(HiddifyOptions.Warp.WireguardConfigStr), &HiddifyOptions.Warp.WireguardConfig) + // if err != nil { + // return nil, err + // } + // } + // if HiddifyOptions.Warp2.WireguardConfigStr != "" { + // err := json.Unmarshal([]byte(HiddifyOptions.Warp2.WireguardConfigStr), &HiddifyOptions.Warp2.WireguardConfig) + // if err != nil { + // return nil, err + // } + // } return &pb.CoreInfoResponse{}, nil } @@ -355,3 +355,41 @@ func Restart(in *pb.StartRequest) (*pb.CoreInfoResponse, error) { resp, gErr := StartService(in) return resp, gErr } + +func SelectOutbound(in *pb.SelectOutboundRequest) (*pb.CoreInfoResponse, error) { + client := libbox.NewCommandClient( + &CommandClientHandler{}, + &libbox.CommandClientOptions{ + Command: libbox.CommandGroup, + }, + ) + defer client.Disconnect() + err := client.Connect() + if err != nil { + return nil, err + } + err = client.SelectOutbound(in.GroupTag, in.OutboundTag) + if err != nil { + return nil, err + } + return &pb.CoreInfoResponse{}, nil +} + +func UrlTest(in *pb.UrlTestRequest) (*pb.CoreInfoResponse, error) { + client := libbox.NewCommandClient( + &CommandClientHandler{}, + &libbox.CommandClientOptions{ + Command: libbox.CommandGroup, + }, + ) + defer client.Disconnect() + err := client.Connect() + if err != nil { + return nil, err + } + err = client.URLTest(in.GroupTag) + if err != nil { + return nil, err + } + return &pb.CoreInfoResponse{}, nil +} diff --git a/v2/db/hiddify_db.go b/v2/db/hiddify_db.go index 1ca00e84..35d27209 100644 --- a/v2/db/hiddify_db.go +++ b/v2/db/hiddify_db.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "os" + "strings" "reflect" "time" @@ -40,6 +41,21 @@ func getDB(name string, readOnly bool) (tmdb.DB, error) { time.Sleep(retryDelay) } + // If the database appears corrupted (manifest), back it up and recreate a fresh one + if err != nil && strings.Contains(err.Error(), "manifest corrupted") { + backup := fmt.Sprintf("%s.bak.%d", dbPath, time.Now().Unix()) + if renameErr := os.Rename(dbPath, backup); renameErr != nil { + log.Printf("Failed to backup corrupted database %s: %v", dbPath, renameErr) + } else { + log.Printf("Backed up corrupted database to %s, attempting to recreate...", backup) + opts := &opt.Options{ReadOnly: false} + db, recErr := tmdb.NewGoLevelDBWithOpts(name, "./data", opts) + if recErr == nil { + return db, nil + } + log.Printf("Recreate database failed: %v", recErr) + } + } return nil, err } diff --git a/v2/grpc_server.go b/v2/grpc_server.go index 28810c71..0c8264ee 100644 --- a/v2/grpc_server.go +++ b/v2/grpc_server.go @@ -1,68 +1,61 @@ -package v2 - -/* -#include "stdint.h" -*/ - -import ( - "log" - "net" - - "github.com/hiddify/hiddify-core/extension" - pb "github.com/hiddify/hiddify-core/hiddifyrpc" - - "google.golang.org/grpc" -) - -type HelloService struct { - pb.UnimplementedHelloServer -} -type CoreService struct { - pb.UnimplementedCoreServer -} - -type TunnelService struct { - pb.UnimplementedTunnelServiceServer -} - -func StartGrpcServer(listenAddressG string, service string) (*grpc.Server, error) { - lis, err := net.Listen("tcp", listenAddressG) - if err != nil { - log.Printf("failed to listen: %v", err) - return nil, err - } - s := grpc.NewServer() - if service == "core" { - - // Setup("./tmp/", "./tmp", "./tmp", 11111, false) - - useFlutterBridge = false - pb.RegisterCoreServer(s, &CoreService{}) - pb.RegisterExtensionHostServiceServer(s, &extension.ExtensionHostService{}) - } else if service == "hello" { - pb.RegisterHelloServer(s, &HelloService{}) - } else if service == "tunnel" { - pb.RegisterTunnelServiceServer(s, &TunnelService{}) - } - log.Printf("Server listening on %s", listenAddressG) - go func() { - if err := s.Serve(lis); err != nil { - log.Printf("failed to serve: %v", err) - } - log.Printf("Server stopped") - // cancel() - }() - return s, nil -} - -func StartCoreGrpcServer(listenAddressG string) (*grpc.Server, error) { - return StartGrpcServer(listenAddressG, "core") -} - -func StartHelloGrpcServer(listenAddressG string) (*grpc.Server, error) { - return StartGrpcServer(listenAddressG, "hello") -} - -func StartTunnelGrpcServer(listenAddressG string) (*grpc.Server, error) { - return StartGrpcServer(listenAddressG, "tunnel") -} +package v2 + +import ( + "log" + "net" + + "github.com/hiddify/hiddify-core/extension" + pb "github.com/hiddify/hiddify-core/hiddifyrpc" + + "google.golang.org/grpc" +) + +type HelloService struct { + pb.UnimplementedHelloServer +} +type CoreService struct { + pb.UnimplementedCoreServer +} +type TunnelService struct { + pb.UnimplementedTunnelServiceServer +} + +func StartGrpcServer(listenAddressG string, service string) (*grpc.Server, error) { + lis, err := net.Listen("tcp", listenAddressG) + if err != nil { + log.Printf("failed to listen: %v", err) + return nil, err + } + s := grpc.NewServer() + switch service { + case "core": + // Setup("./tmp/", "./tmp", "./tmp", 11111, false) + useFlutterBridge = false + pb.RegisterCoreServer(s, &CoreService{}) + pb.RegisterExtensionHostServiceServer(s, &extension.ExtensionHostService{}) + case "hello": + pb.RegisterHelloServer(s, &HelloService{}) + case "tunnel": + pb.RegisterTunnelServiceServer(s, &TunnelService{}) + } + log.Printf("Server listening on %s", listenAddressG) + go func() { + if err := s.Serve(lis); err != nil { + log.Printf("failed to serve: %v", err) + } + // log.Printf("Server stopped") + // cancel() + }() + return s, nil +} + +func StartCoreGrpcServer(listenAddressG string) (*grpc.Server, error) { + return StartGrpcServer(listenAddressG, "core") +} +func StartHelloGrpcServer(listenAddressG string) (*grpc.Server, error) { + return StartGrpcServer(listenAddressG, "hello") +} + +func StartTunnelGrpcServer(listenAddressG string) (*grpc.Server, error) { + return StartGrpcServer(listenAddressG, "tunnel") +} diff --git a/v2/logproto.go b/v2/logproto.go index ee2c0c0f..8e61d602 100644 --- a/v2/logproto.go +++ b/v2/logproto.go @@ -1,44 +1,44 @@ -package v2 - -import ( - "fmt" - "time" - - pb "github.com/hiddify/hiddify-core/hiddifyrpc" - "github.com/sagernet/sing/common/observable" - "google.golang.org/grpc" -) - -func NewObserver[T any](listenerBufferSize int) *observable.Observer[T] { - return observable.NewObserver(observable.NewSubscriber[T](listenerBufferSize), listenerBufferSize) -} - -var logObserver = NewObserver[pb.LogMessage](10) - -func Log(level pb.LogLevel, typ pb.LogType, message string) { - if level != pb.LogLevel_DEBUG { - fmt.Printf("%s %s %s\n", level, typ, message) - } - logObserver.Emit(pb.LogMessage{ - Level: level, - Type: typ, - Message: message, - }) -} - -func (s *CoreService) LogListener(req *pb.Empty, stream grpc.ServerStreamingServer[pb.LogMessage]) error { - logSub, stopch, _ := logObserver.Subscribe() - defer logObserver.UnSubscribe(logSub) - - for { - select { - case <-stream.Context().Done(): - return nil - case <-stopch: - return nil - case info := <-logSub: - stream.Send(&info) - case <-time.After(500 * time.Millisecond): - } - } -} +package v2 + +import ( + "fmt" + "time" + + pb "github.com/hiddify/hiddify-core/hiddifyrpc" + "github.com/sagernet/sing/common/observable" + "google.golang.org/grpc" +) + +func NewObserver[T any](listenerBufferSize int) *observable.Observer[T] { + return observable.NewObserver(observable.NewSubscriber[T](listenerBufferSize), listenerBufferSize) +} + +var logObserver = NewObserver[*pb.LogMessage](10) + +func Log(level pb.LogLevel, typ pb.LogType, message string) { + if level != pb.LogLevel_DEBUG { + fmt.Printf("%s %s %s\n", level, typ, message) + } + logObserver.Emit(&pb.LogMessage{ + Level: level, + Type: typ, + Message: message, + }) +} + +func (s *CoreService) LogListener(req *pb.Empty, stream grpc.ServerStreamingServer[pb.LogMessage]) error { + logSub, stopch, _ := logObserver.Subscribe() + defer logObserver.UnSubscribe(logSub) + + for { + select { + case <-stream.Context().Done(): + return nil + case <-stopch: + return nil + case info := <-logSub: + stream.Send(info) + case <-time.After(500 * time.Millisecond): + } + } +} diff --git a/v2/observers.go b/v2/observers.go new file mode 100644 index 00000000..1bc495dd --- /dev/null +++ b/v2/observers.go @@ -0,0 +1,11 @@ +package v2 + +import ( + pb "github.com/hiddify/hiddify-core/hiddifyrpc" +) + +var ( + systemInfoObserver = NewObserver[*pb.SystemInfo](10) + outboundsInfoObserver = NewObserver[*pb.OutboundGroupList](10) + mainOutboundsInfoObserver = NewObserver[*pb.OutboundGroupList](10) +) diff --git a/v2/old_command_client.go b/v2/old_command_client.go index 962c0827..9dd71511 100644 --- a/v2/old_command_client.go +++ b/v2/old_command_client.go @@ -1,7 +1,7 @@ package v2 import ( - "encoding/json" + json "github.com/goccy/go-json" "fmt" "github.com/hiddify/hiddify-core/bridge" @@ -18,6 +18,11 @@ type OldCommandClientHandler struct { logger log.Logger } +func (cch *OldCommandClientHandler) WriteConnections(message *libbox.Connections) { + // No-op for legacy client + cch.logger.Debug("connections update") +} + func (cch *OldCommandClientHandler) Connected() { cch.logger.Debug("CONNECTED") } @@ -25,7 +30,6 @@ func (cch *OldCommandClientHandler) Connected() { func (cch *OldCommandClientHandler) Disconnected(message string) { cch.logger.Debug("DISCONNECTED: ", message) } - func (cch *OldCommandClientHandler) ClearLog() { cch.logger.Debug("clear log") } @@ -34,6 +38,17 @@ func (cch *OldCommandClientHandler) WriteLog(message string) { cch.logger.Debug("log: ", message) } +// New in libbox v1.13 +func (cch *OldCommandClientHandler) ClearLogs() { + cch.logger.Debug("clear logs") +} +func (cch *OldCommandClientHandler) WriteLogs(messageList libbox.StringIterator) { + for messageList.HasNext() { + msg := messageList.Next() + cch.logger.Debug("log:", msg) + } +} + func (cch *OldCommandClientHandler) WriteStatus(message *libbox.StatusMessage) { msg, err := json.Marshal( map[string]int64{ diff --git a/v2/old_commands.go b/v2/old_commands.go index f7505d97..1526d8b5 100644 --- a/v2/old_commands.go +++ b/v2/old_commands.go @@ -5,9 +5,8 @@ import ( ) var ( - oldStatusClient *libbox.CommandClient - oldGroupClient *libbox.CommandClient - oldGroupInfoOnlyClient *libbox.CommandClient + oldStatusClient *libbox.CommandClient + oldGroupClient *libbox.CommandClient ) func StartCommand(command int32, port int64) error { @@ -20,7 +19,7 @@ func StartCommand(command int32, port int64) error { }, &libbox.CommandClientOptions{ Command: libbox.CommandStatus, - StatusInterval: 1000000000, //1000ms debounce + StatusInterval: 1000000000, // 1000ms debounce }, ) return oldStatusClient.Connect() @@ -32,40 +31,29 @@ func StartCommand(command int32, port int64) error { }, &libbox.CommandClientOptions{ Command: libbox.CommandGroup, - StatusInterval: 300000000, //300ms debounce + StatusInterval: 300000000, // 300ms debounce }, ) return oldGroupClient.Connect() - case libbox.CommandGroupInfoOnly: - oldGroupInfoOnlyClient = libbox.NewCommandClient( - &OldCommandClientHandler{ - port: port, - logger: coreLogFactory.NewLogger("[GroupInfoOnly Command Client]"), - }, - &libbox.CommandClientOptions{ - Command: libbox.CommandGroupInfoOnly, - StatusInterval: 300000000, //300ms debounce - }, - ) - return oldGroupInfoOnlyClient.Connect() + default: + return nil } - return nil } func StopCommand(command int32) error { switch command { case libbox.CommandStatus: - err := oldStatusClient.Disconnect() - oldStatusClient = nil - return err + if oldStatusClient != nil { + err := oldStatusClient.Disconnect() + oldStatusClient = nil + return err + } case libbox.CommandGroup: - err := oldGroupClient.Disconnect() - oldGroupClient = nil - return err - case libbox.CommandGroupInfoOnly: - err := oldGroupInfoOnlyClient.Disconnect() - oldGroupInfoOnlyClient = nil - return err + if oldGroupClient != nil { + err := oldGroupClient.Disconnect() + oldGroupClient = nil + return err + } } return nil } diff --git a/v2/platform_stub.go b/v2/platform_stub.go new file mode 100644 index 00000000..888c3644 --- /dev/null +++ b/v2/platform_stub.go @@ -0,0 +1,49 @@ +package v2 + +import ( + "github.com/sagernet/sing-box/experimental/libbox" +) + +type platformStub struct{} + +// Local DNS +func (p *platformStub) LocalDNSTransport() libbox.LocalDNSTransport { return nil } + +// Interface control +func (p *platformStub) UsePlatformAutoDetectInterfaceControl() bool { return false } +func (p *platformStub) AutoDetectInterfaceControl(fd int32) error { return nil } + +// TUN +func (p *platformStub) OpenTun(options libbox.TunOptions) (int32, error) { return 0, nil } + +// Logs +func (p *platformStub) WriteLog(message string) {} + +// ProcFS / UID +func (p *platformStub) UseProcFS() bool { return false } +func (p *platformStub) FindConnectionOwner(ipProtocol int32, sourceAddress string, sourcePort int32, destinationAddress string, destinationPort int32) (int32, error) { + return 0, nil +} +func (p *platformStub) PackageNameByUid(uid int32) (string, error) { return "", nil } +func (p *platformStub) UIDByPackageName(packageName string) (int32, error) { + return 0, nil +} + +// Default interface monitor +func (p *platformStub) StartDefaultInterfaceMonitor(listener libbox.InterfaceUpdateListener) error { return nil } +func (p *platformStub) CloseDefaultInterfaceMonitor(listener libbox.InterfaceUpdateListener) error { return nil } + +// Interface getter +func (p *platformStub) GetInterfaces() (libbox.NetworkInterfaceIterator, error) { return nil, nil } + +// NE extension / network flags +func (p *platformStub) UnderNetworkExtension() bool { return false } +func (p *platformStub) IncludeAllNetworks() bool { return true } + +// WIFI / Certs / DNS cache +func (p *platformStub) ReadWIFIState() *libbox.WIFIState { return nil } +func (p *platformStub) SystemCertificates() libbox.StringIterator { return nil } +func (p *platformStub) ClearDNSCache() {} + +// Notifications +func (p *platformStub) SendNotification(notification *libbox.Notification) error { return nil } diff --git a/v2/service.go b/v2/service.go index a5273310..b2b7fcc1 100644 --- a/v2/service.go +++ b/v2/service.go @@ -1,32 +1,24 @@ package v2 import ( - "context" + json "github.com/goccy/go-json" "io" - "os" - "runtime" runtimeDebug "runtime/debug" "time" + "github.com/hiddify/hiddify-core/config" "github.com/hiddify/hiddify-core/v2/service_manager" - B "github.com/sagernet/sing-box" - "github.com/sagernet/sing-box/common/urltest" "github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" E "github.com/sagernet/sing/common/exceptions" - "github.com/sagernet/sing/service" - "github.com/sagernet/sing/service/filemanager" - "github.com/sagernet/sing/service/pause" ) var ( - sWorkingPath string - sTempPath string - sUserID int - sGroupID int - statusPropagationPort int64 + sWorkingPath string + sTempPath string + statusPropagationPort int64 ) func InitHiddifyService() error { @@ -34,68 +26,52 @@ func InitHiddifyService() error { } func Setup(basePath string, workingPath string, tempPath string, statusPort int64, debug bool) error { - statusPropagationPort = int64(statusPort) - tcpConn := runtime.GOOS == "windows" // TODO add TVOS - libbox.Setup(basePath, workingPath, tempPath, tcpConn) - sWorkingPath = workingPath - os.Chdir(sWorkingPath) - sTempPath = tempPath - sUserID = os.Getuid() - sGroupID = os.Getgid() + statusPropagationPort = int64(statusPort) + _ = libbox.Setup(&libbox.SetupOptions{ + BasePath: basePath, + WorkingPath: workingPath, + TempPath: tempPath, + // Username: "", IsTVOS: false, FixAndroidStack: false + }) + sWorkingPath = workingPath + sTempPath = tempPath - var defaultWriter io.Writer - if !debug { - defaultWriter = io.Discard - } - factory, err := log.New( - log.Options{ - DefaultWriter: defaultWriter, - BaseTime: time.Now(), - Observable: true, - // Options: option.LogOptions{ - // Disabled: false, - // Level: "trace", - // Output: "stdout", - // }, - }) - coreLogFactory = factory + var defaultWriter io.Writer + if !debug { + defaultWriter = io.Discard + } + factory, err := log.New(log.Options{ + DefaultWriter: defaultWriter, + BaseTime: time.Now(), + Observable: true, + }) + coreLogFactory = factory - if err != nil { - return E.Cause(err, "create logger") - } - return InitHiddifyService() + if err != nil { + return E.Cause(err, "create logger") + } + return InitHiddifyService() } func NewService(options option.Options) (*libbox.BoxService, error) { - runtimeDebug.FreeOSMemory() - ctx, cancel := context.WithCancel(context.Background()) - ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID) - urlTestHistoryStorage := urltest.NewHistoryStorage() - ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage) - instance, err := B.New(B.Options{ - Context: ctx, - Options: options, - }) - if err != nil { - cancel() - return nil, E.Cause(err, "create service") - } - runtimeDebug.FreeOSMemory() - service := libbox.NewBoxService( - ctx, - cancel, - instance, - service.FromContext[pause.Manager](ctx), - urlTestHistoryStorage, - ) - return &service, nil + runtimeDebug.FreeOSMemory() + // Convert options to JSON for libbox.NewService API + cfg, err := config.ToJson(options) + if err != nil { + return nil, E.Cause(err, "encode config") + } + bs, err := libbox.NewService(cfg, &platformStub{}) + if err != nil { + return nil, E.Cause(err, "create service") + } + runtimeDebug.FreeOSMemory() + return bs, nil } func readOptions(configContent string) (option.Options, error) { - var options option.Options - err := options.UnmarshalJSON([]byte(configContent)) - if err != nil { - return option.Options{}, E.Cause(err, "decode config") - } - return options, nil + var options option.Options + if err := json.Unmarshal([]byte(configContent), &options); err != nil { + return option.Options{}, E.Cause(err, "decode config") + } + return options, nil } diff --git a/v2/service_manager/hiddify.go b/v2/service_manager/hiddify.go index 5d6ef28f..de4ce21b 100644 --- a/v2/service_manager/hiddify.go +++ b/v2/service_manager/hiddify.go @@ -10,7 +10,7 @@ var ( ) func RegisterPreservice(service adapter.Service) { - preservices = append(services, service) + preservices = append(preservices, service) } func Register(service adapter.Service) { @@ -19,14 +19,16 @@ func Register(service adapter.Service) { func StartServices() error { CloseServices() - for _, service := range preservices { - if err := service.Start(); err != nil { - return err + for _, stage := range adapter.ListStartStages { + for _, service := range preservices { + if err := service.Start(stage); err != nil { + return err + } } - } - for _, service := range services { - if err := service.Start(); err != nil { - return err + for _, service := range services { + if err := service.Start(stage); err != nil { + return err + } } } return nil diff --git a/v2/standalone.go b/v2/standalone.go index 173c9eef..963d0dc5 100644 --- a/v2/standalone.go +++ b/v2/standalone.go @@ -1,248 +1,235 @@ -package v2 - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "os" - "os/signal" - "runtime" - "strconv" - "strings" - "syscall" - "time" - - "github.com/hiddify/hiddify-core/config" - pb "github.com/hiddify/hiddify-core/hiddifyrpc" - - "github.com/sagernet/sing-box/option" -) - -func RunStandalone(hiddifySettingPath string, configPath string, defaultConfig config.HiddifyOptions) error { - fmt.Println("Running in standalone mode") - useFlutterBridge = false - current, err := readAndBuildConfig(hiddifySettingPath, configPath, &defaultConfig) - if err != nil { - fmt.Printf("Error in read and build config %v", err) - return err - } - - go StartService(&pb.StartRequest{ - ConfigContent: current.Config, - EnableOldCommandServer: false, - DelayStart: false, - EnableRawConfig: true, - }) - go updateConfigInterval(current, hiddifySettingPath, configPath) - - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) - - fmt.Printf("Waiting for CTRL+C to stop\n") - <-sigChan - fmt.Printf("CTRL+C recived-->stopping\n") - _, err = Stop() - - return err -} - -type ConfigResult struct { - Config string - RefreshInterval int - HiddifyHiddifyOptions *config.HiddifyOptions -} - -func readAndBuildConfig(hiddifySettingPath string, configPath string, defaultConfig *config.HiddifyOptions) (ConfigResult, error) { - var result ConfigResult - - result, err := readConfigContent(configPath) - if err != nil { - return result, err - } - - hiddifyconfig := config.DefaultHiddifyOptions() - - if defaultConfig != nil { - hiddifyconfig = defaultConfig - } - - if hiddifySettingPath != "" { - hiddifyconfig, err = ReadHiddifyOptionsAt(hiddifySettingPath) - if err != nil { - return result, err - } - } - - result.HiddifyHiddifyOptions = hiddifyconfig - result.Config, err = buildConfig(result.Config, *result.HiddifyHiddifyOptions) - if err != nil { - return result, err - } - - return result, nil -} - -func readConfigContent(configPath string) (ConfigResult, error) { - var content string - var refreshInterval int - - if strings.HasPrefix(configPath, "http://") || strings.HasPrefix(configPath, "https://") { - client := &http.Client{} - - // Create a new request - req, err := http.NewRequest("GET", configPath, nil) - if err != nil { - fmt.Println("Error creating request:", err) - return ConfigResult{}, err - } - req.Header.Set("User-Agent", "HiddifyNext/2.3.1 ("+runtime.GOOS+") like ClashMeta v2ray sing-box") - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error making GET request:", err) - return ConfigResult{}, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return ConfigResult{}, fmt.Errorf("failed to read config body: %w", err) - } - content = string(body) - refreshInterval, _ = extractRefreshInterval(resp.Header, content) - fmt.Printf("Refresh interval: %d\n", refreshInterval) - } else { - data, err := ioutil.ReadFile(configPath) - if err != nil { - return ConfigResult{}, fmt.Errorf("failed to read config file: %w", err) - } - content = string(data) - } - - return ConfigResult{ - Config: content, - RefreshInterval: refreshInterval, - }, nil -} - -func extractRefreshInterval(header http.Header, bodyStr string) (int, error) { - refreshIntervalStr := header.Get("profile-update-interval") - if refreshIntervalStr != "" { - refreshInterval, err := strconv.Atoi(refreshIntervalStr) - if err != nil { - return 0, fmt.Errorf("failed to parse refresh interval from header: %w", err) - } - return refreshInterval, nil - } - - lines := strings.Split(bodyStr, "\n") - for _, line := range lines { - line = strings.TrimSpace(line) - if strings.HasPrefix(line, "//profile-update-interval:") || strings.HasPrefix(line, "#profile-update-interval:") { - parts := strings.SplitN(line, ":", 2) - str := strings.TrimSpace(parts[1]) - refreshInterval, err := strconv.Atoi(str) - if err != nil { - return 0, fmt.Errorf("failed to parse refresh interval from body: %w", err) - } - return refreshInterval, nil - } - } - return 0, nil -} - -func buildConfig(configContent string, options config.HiddifyOptions) (string, error) { - parsedContent, err := config.ParseConfigContent(configContent, true, &options, false) - if err != nil { - return "", fmt.Errorf("failed to parse config content: %w", err) - } - singconfigs, err := readConfigBytes([]byte(parsedContent)) - if err != nil { - return "", err - } - - finalconfig, err := config.BuildConfig(options, *singconfigs) - if err != nil { - return "", fmt.Errorf("failed to build config: %w", err) - } - - finalconfig.Log.Output = "" - finalconfig.Experimental.ClashAPI.ExternalUI = "webui" - if options.AllowConnectionFromLAN { - finalconfig.Experimental.ClashAPI.ExternalController = "0.0.0.0:6756" - } else { - finalconfig.Experimental.ClashAPI.ExternalController = "127.0.0.1:6756" - } - - fmt.Printf("Open http://localhost:6756/ui/?secret=%s in your browser\n", finalconfig.Experimental.ClashAPI.Secret) - - if err := Setup("./", "./", "./tmp", 0, false); err != nil { - return "", fmt.Errorf("failed to set up global configuration: %w", err) - } - - configStr, err := config.ToJson(*finalconfig) - if err != nil { - return "", fmt.Errorf("failed to convert config to JSON: %w", err) - } - - return configStr, nil -} - -func updateConfigInterval(current ConfigResult, hiddifySettingPath string, configPath string) { - if current.RefreshInterval <= 0 { - return - } - - for { - <-time.After(time.Duration(current.RefreshInterval) * time.Hour) - new, err := readAndBuildConfig(hiddifySettingPath, configPath, current.HiddifyHiddifyOptions) - if err != nil { - continue - } - if new.Config != current.Config { - go Stop() - go StartService(&pb.StartRequest{ - ConfigContent: new.Config, - DelayStart: false, - EnableOldCommandServer: false, - DisableMemoryLimit: false, - EnableRawConfig: true, - }) - } - current = new - } -} - -func readConfigBytes(content []byte) (*option.Options, error) { - var options option.Options - err := options.UnmarshalJSON(content) - if err != nil { - return nil, err - } - return &options, nil -} - -func ReadHiddifyOptionsAt(path string) (*config.HiddifyOptions, error) { - content, err := os.ReadFile(path) - if err != nil { - return nil, err - } - var options config.HiddifyOptions - err = json.Unmarshal(content, &options) - if err != nil { - return nil, err - } - if options.Warp.WireguardConfigStr != "" { - err := json.Unmarshal([]byte(options.Warp.WireguardConfigStr), &options.Warp.WireguardConfig) - if err != nil { - return nil, err - } - } - if options.Warp2.WireguardConfigStr != "" { - err := json.Unmarshal([]byte(options.Warp2.WireguardConfigStr), &options.Warp2.WireguardConfig) - if err != nil { - return nil, err - } - } - return &options, nil -} +package v2 + +import ( + json "github.com/goccy/go-json" + "fmt" + "io" + "net/http" + "os" + "os/signal" + "runtime" + "strconv" + "strings" + "syscall" + "time" + + "github.com/hiddify/hiddify-core/config" + pb "github.com/hiddify/hiddify-core/hiddifyrpc" + + "github.com/sagernet/sing-box/option" +) + +func RunStandalone(hiddifySettingPath string, configPath string, defaultConfig config.HiddifyOptions) error { + fmt.Println("Running in standalone mode") + useFlutterBridge = false + current, err := readAndBuildConfig(hiddifySettingPath, configPath, &defaultConfig) + if err != nil { + fmt.Printf("Error in read and build config %v", err) + return err + } + + go StartService(&pb.StartRequest{ + ConfigContent: current.Config, + EnableOldCommandServer: false, + DelayStart: false, + EnableRawConfig: true, + }) + go updateConfigInterval(current, hiddifySettingPath, configPath) + + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) + + fmt.Printf("Waiting for CTRL+C to stop\n") + <-sigChan + fmt.Printf("CTRL+C recived-->stopping\n") + _, err = Stop() + + return err +} + +type ConfigResult struct { + Config string + RefreshInterval int + HiddifyHiddifyOptions *config.HiddifyOptions +} + +func readAndBuildConfig(hiddifySettingPath string, configPath string, defaultConfig *config.HiddifyOptions) (ConfigResult, error) { + var result ConfigResult + + result, err := readConfigContent(configPath) + if err != nil { + return result, err + } + + hiddifyconfig := config.DefaultHiddifyOptions() + + if defaultConfig != nil { + hiddifyconfig = defaultConfig + } + + if hiddifySettingPath != "" { + hiddifyconfig, err = ReadHiddifyOptionsAt(hiddifySettingPath) + if err != nil { + return result, err + } + } + + result.HiddifyHiddifyOptions = hiddifyconfig + result.Config, err = buildConfig(result.Config, *result.HiddifyHiddifyOptions) + if err != nil { + return result, err + } + + return result, nil +} + +func readConfigContent(configPath string) (ConfigResult, error) { + var content string + var refreshInterval int + + if strings.HasPrefix(configPath, "http://") || strings.HasPrefix(configPath, "https://") { + client := &http.Client{} + + // Create a new request + req, err := http.NewRequest("GET", configPath, nil) + if err != nil { + fmt.Println("Error creating request:", err) + return ConfigResult{}, err + } + req.Header.Set("User-Agent", "HiddifyNext/2.3.1 ("+runtime.GOOS+") like ClashMeta v2ray sing-box") + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error making GET request:", err) + return ConfigResult{}, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return ConfigResult{}, fmt.Errorf("failed to read config body: %w", err) + } + content = string(body) + refreshInterval, _ = extractRefreshInterval(resp.Header, content) + fmt.Printf("Refresh interval: %d\n", refreshInterval) + } else { + data, err := os.ReadFile(configPath) + if err != nil { + return ConfigResult{}, fmt.Errorf("failed to read config file: %w", err) + } + content = string(data) + } + + return ConfigResult{ + Config: content, + RefreshInterval: refreshInterval, + }, nil +} + +func extractRefreshInterval(header http.Header, bodyStr string) (int, error) { + refreshIntervalStr := header.Get("profile-update-interval") + if refreshIntervalStr != "" { + refreshInterval, err := strconv.Atoi(refreshIntervalStr) + if err != nil { + return 0, fmt.Errorf("failed to parse refresh interval from header: %w", err) + } + return refreshInterval, nil + } + + lines := strings.Split(bodyStr, "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + if strings.HasPrefix(line, "//profile-update-interval:") || strings.HasPrefix(line, "#profile-update-interval:") { + parts := strings.SplitN(line, ":", 2) + str := strings.TrimSpace(parts[1]) + refreshInterval, err := strconv.Atoi(str) + if err != nil { + return 0, fmt.Errorf("failed to parse refresh interval from body: %w", err) + } + return refreshInterval, nil + } + } + return 0, nil +} + +func buildConfig(configContent string, options config.HiddifyOptions) (string, error) { + parsedContent, err := config.ParseConfigContent(configContent, true, &options, false) + if err != nil { + return "", fmt.Errorf("failed to parse config content: %w", err) + } + singconfigs, err := readConfigBytes([]byte(parsedContent)) + if err != nil { + return "", err + } + + finalconfig, err := config.BuildConfig(options, *singconfigs) + if err != nil { + return "", fmt.Errorf("failed to build config: %w", err) + } + + finalconfig.Log.Output = "" + finalconfig.Experimental.ClashAPI.ExternalUI = "webui" + if options.AllowConnectionFromLAN { + finalconfig.Experimental.ClashAPI.ExternalController = "0.0.0.0:6756" + } else { + finalconfig.Experimental.ClashAPI.ExternalController = "127.0.0.1:6756" + } + + fmt.Printf("Open http://localhost:6756/ui/?secret=%s in your browser\n", finalconfig.Experimental.ClashAPI.Secret) + + if err := Setup("./", "./", "./tmp", 0, false); err != nil { + return "", fmt.Errorf("failed to set up global configuration: %w", err) + } + + configStr, err := config.ToJson(*finalconfig) + if err != nil { + return "", fmt.Errorf("failed to convert config to JSON: %w", err) + } + + return configStr, nil +} + +func updateConfigInterval(current ConfigResult, hiddifySettingPath string, configPath string) { + if current.RefreshInterval <= 0 { + return + } + + for { + <-time.After(time.Duration(current.RefreshInterval) * time.Hour) + new, err := readAndBuildConfig(hiddifySettingPath, configPath, current.HiddifyHiddifyOptions) + if err != nil { + continue + } + if new.Config != current.Config { + go Stop() + go StartService(&pb.StartRequest{ + ConfigContent: new.Config, + DelayStart: false, + EnableOldCommandServer: false, + DisableMemoryLimit: false, + EnableRawConfig: true, + }) + } + current = new + } +} + +func readConfigBytes(content []byte) (*option.Options, error) { + var options option.Options + if err := json.Unmarshal(content, &options); err != nil { + return nil, err + } + return &options, nil +} + +func ReadHiddifyOptionsAt(path string) (*config.HiddifyOptions, error) { + content, err := os.ReadFile(path) + if err != nil { + return nil, err + } + var options config.HiddifyOptions + err = json.Unmarshal(content, &options) + if err != nil { + return nil, err + } + return &options, nil +} diff --git a/v2/system_proxy.go b/v2/system_proxy.go index ea249e60..640874d5 100644 --- a/v2/system_proxy.go +++ b/v2/system_proxy.go @@ -1,44 +1,57 @@ -package v2 - -import ( - "context" - - pb "github.com/hiddify/hiddify-core/hiddifyrpc" - "github.com/sagernet/sing-box/experimental/libbox" -) - -func (s *CoreService) GetSystemProxyStatus(ctx context.Context, empty *pb.Empty) (*pb.SystemProxyStatus, error) { - return GetSystemProxyStatus(ctx, empty) -} -func GetSystemProxyStatus(ctx context.Context, empty *pb.Empty) (*pb.SystemProxyStatus, error) { - status, err := libbox.NewStandaloneCommandClient().GetSystemProxyStatus() - - if err != nil { - return nil, err - } - - return &pb.SystemProxyStatus{ - Available: status.Available, - Enabled: status.Enabled, - }, nil -} - -func (s *CoreService) SetSystemProxyEnabled(ctx context.Context, in *pb.SetSystemProxyEnabledRequest) (*pb.Response, error) { - return SetSystemProxyEnabled(ctx, in) -} -func SetSystemProxyEnabled(ctx context.Context, in *pb.SetSystemProxyEnabledRequest) (*pb.Response, error) { - err := libbox.NewStandaloneCommandClient().SetSystemProxyEnabled(in.IsEnabled) - - if err != nil { - return &pb.Response{ - ResponseCode: pb.ResponseCode_FAILED, - Message: err.Error(), - }, err - } - - return &pb.Response{ - ResponseCode: pb.ResponseCode_OK, - Message: "", - }, nil - -} +package v2 + +import ( + "context" + "os" + + pb "github.com/hiddify/hiddify-core/hiddifyrpc" + "github.com/sagernet/sing-box/experimental/libbox" +) + +func (s *CoreService) GetSystemProxyStatus(ctx context.Context, empty *pb.Empty) (*pb.SystemProxyStatus, error) { + return GetSystemProxyStatus(ctx, empty) +} +func GetSystemProxyStatus(ctx context.Context, empty *pb.Empty) (*pb.SystemProxyStatus, error) { + status, err := libbox.NewStandaloneCommandClient().GetSystemProxyStatus() + + if err != nil { + return nil, err + } + + return &pb.SystemProxyStatus{ + Available: status.Available, + Enabled: status.Enabled, + }, nil +} + +func (s *CoreService) SetSystemProxyEnabled(ctx context.Context, in *pb.SetSystemProxyEnabledRequest) (*pb.Response, error) { + return SetSystemProxyEnabled(ctx, in) +} +func SetSystemProxyEnabled(ctx context.Context, in *pb.SetSystemProxyEnabledRequest) (*pb.Response, error) { + err := libbox.NewStandaloneCommandClient().SetSystemProxyEnabled(in.IsEnabled) + + if err != nil { + return &pb.Response{ + ResponseCode: pb.ResponseCode_FAILED, + Message: err.Error(), + }, err + } + + // Also clear common proxy environment variables if disabling + if !in.IsEnabled { + keys := []string{ + "http_proxy", "https_proxy", "ftp_proxy", "all_proxy", + "HTTP_PROXY", "HTTPS_PROXY", "FTP_PROXY", "ALL_PROXY", + "no_proxy", "NO_PROXY", + } + for _, k := range keys { + _ = os.Unsetenv(k) + } + } + + return &pb.Response{ + ResponseCode: pb.ResponseCode_OK, + Message: "", + }, nil + +} diff --git a/v2/tunnel_platform_service.go b/v2/tunnel_platform_service_v113.go similarity index 69% rename from v2/tunnel_platform_service.go rename to v2/tunnel_platform_service_v113.go index 431d09b4..54354942 100644 --- a/v2/tunnel_platform_service.go +++ b/v2/tunnel_platform_service_v113.go @@ -35,11 +35,7 @@ func getCurrentExecutableDirectory() string { if err != nil { return "" } - - // Extract the directory (folder) containing the executable - executableDirectory := filepath.Dir(executablePath) - - return executableDirectory + return filepath.Dir(executablePath) } func StartTunnelService(goArg string) (int, string) { @@ -57,7 +53,6 @@ func StartTunnelService(goArg string) (int, string) { prg := &hiddifyNext{} s, err := service.New(prg, svcConfig) if err != nil { - // log.Printf("Error: %v", err) return 1, fmt.Sprintf("Error: %v", err) } @@ -69,8 +64,7 @@ func StartTunnelService(goArg string) (int, string) { if err != nil { log.Printf("Error: %v", err) } - err = s.Run() - if err != nil { + if err = s.Run(); err != nil { logger.Error(err) return 3, fmt.Sprintf("Error: %v", err) } @@ -79,11 +73,11 @@ func StartTunnelService(goArg string) (int, string) { func control(s service.Service, goArg string) (int, string) { dolog := false - var err error status, serr := s.Status() if dolog { fmt.Printf("Current Status: %+v %+v!\n", status, serr) } + switch goArg { case "uninstall": if status == service.StatusRunning { @@ -92,34 +86,51 @@ func control(s service.Service, goArg string) (int, string) { if dolog { fmt.Printf("Tunnel Service Uninstalled Successfully.\n") } - err = s.Uninstall() + if err := s.Uninstall(); err != nil { + return 2, fmt.Sprintf("Error: %v", err) + } + return 0, "Tunnel Service Uninstalled Successfully." + case "start": - if status == service.StatusRunning { + switch status { + case service.StatusRunning: if dolog { fmt.Printf("Tunnel Service Already Running.\n") } return 0, "Tunnel Service Already Running." - } else if status == service.StatusUnknown { - s.Uninstall() - s.Install() + case service.StatusUnknown: + _ = s.Uninstall() + _ = s.Install() status, serr = s.Status() if dolog { fmt.Printf("Check status again: %+v %+v!", status, serr) } + fallthrough + default: + if status != service.StatusRunning { + if err := s.Start(); err != nil { + return 2, fmt.Sprintf("Error: %v", err) + } + } } - if status != service.StatusRunning { - err = s.Start() - } + return 0, "Tunnel Service Started." + case "install": - s.Uninstall() - err = s.Install() + _ = s.Uninstall() + if err := s.Install(); err != nil { + return 2, fmt.Sprintf("Error: %v", err) + } status, serr = s.Status() if dolog { fmt.Printf("Check Status Again: %+v %+v", status, serr) } if status != service.StatusRunning { - err = s.Start() + if err := s.Start(); err != nil { + return 2, fmt.Sprintf("Error: %v", err) + } } + return 0, "Tunnel Service Installed." + case "stop": if status == service.StatusStopped { if dolog { @@ -127,21 +138,15 @@ func control(s service.Service, goArg string) (int, string) { } return 0, "Tunnel Service Already Stopped." } - err = s.Stop() - default: - err = service.Control(s, goArg) - } - if err == nil { - out := fmt.Sprintf("Tunnel Service %sed Successfully.", goArg) - if dolog { - fmt.Printf(out) + if err := s.Stop(); err != nil { + return 2, fmt.Sprintf("Error: %v", err) } - return 0, out - } else { - out := fmt.Sprintf("Error: %v", err) - if dolog { - log.Printf(out) + return 0, "Tunnel Service Stopped." + + default: + if err := service.Control(s, goArg); err != nil { + return 2, fmt.Sprintf("Error: %v", err) } - return 2, out + return 0, fmt.Sprintf("Tunnel Service %s Successfully.", goArg) } } diff --git a/v2/warp.go b/v2/warp.go deleted file mode 100644 index 145a2468..00000000 --- a/v2/warp.go +++ /dev/null @@ -1,32 +0,0 @@ -package v2 - -import ( - "context" - - "github.com/hiddify/hiddify-core/config" - pb "github.com/hiddify/hiddify-core/hiddifyrpc" -) - -func (s *CoreService) GenerateWarpConfig(ctx context.Context, in *pb.GenerateWarpConfigRequest) (*pb.WarpGenerationResponse, error) { - return GenerateWarpConfig(in) -} -func GenerateWarpConfig(in *pb.GenerateWarpConfigRequest) (*pb.WarpGenerationResponse, error) { - identity, log, wg, err := config.GenerateWarpInfo(in.LicenseKey, in.AccountId, in.AccessToken) - if err != nil { - return nil, err - } - return &pb.WarpGenerationResponse{ - Account: &pb.WarpAccount{ - AccountId: identity.ID, - AccessToken: identity.Token, - }, - Config: &pb.WarpWireguardConfig{ - PrivateKey: wg.PrivateKey, - LocalAddressIpv4: wg.LocalAddressIPv4, - LocalAddressIpv6: wg.LocalAddressIPv6, - PeerPublicKey: wg.PeerPublicKey, - ClientId: wg.ClientID, - }, - Log: log, - }, nil -}