From 4a37a53ca8fd2857d562d93c91e559063016a0bd Mon Sep 17 00:00:00 2001 From: "github-action[bot]" Date: Wed, 5 Nov 2025 19:38:45 +0100 Subject: [PATCH] Update On Wed Nov 5 19:38:45 CET 2025 --- .github/update.log | 1 + clash-meta/go.mod | 2 +- clash-meta/go.sum | 4 +- clash-nyanpasu/backend/Cargo.lock | 70 ++-- clash-nyanpasu/backend/tauri/Cargo.toml | 12 +- clash-nyanpasu/frontend/nyanpasu/package.json | 8 +- clash-nyanpasu/frontend/ui/package.json | 4 +- clash-nyanpasu/manifest/version.json | 8 +- clash-nyanpasu/pnpm-lock.yaml | 159 ++++--- ...0-0018-arm64-setup-Fix-build-warning.patch | 2 +- ...-for-all-the-downstream-rpi-sound-ca.patch | 4 +- ...Disable-TCP-Segmentation-Offload-TSO.patch | 2 +- ...e-link-events-to-minimize-poll-storm.patch | 2 +- ...-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch | 2 +- ...8xx-Enable-LEDs-and-auto-negotiation.patch | 6 +- ...hci_fixup_endpoint-for-interval-adju.patch | 4 +- ...d-add-the-endpoint-context-in-xhci_f.patch | 2 +- ...ci_sync-Add-fallback-bd-address-prop.patch | 4 +- ...7xx-Read-modem-line-state-at-startup.patch | 2 +- ...-quirks-add-link-TRB-quirk-for-VL805.patch | 2 +- ...b-xhci-add-VLI_SS_BULK_OUT_BUG-quirk.patch | 8 +- ...5-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch | 8 +- ...ore-event-ring-segment-table-entries.patch | 2 +- ...78xx-Read-initial-EEE-status-from-DT.patch | 2 +- ...th-hci_sync-Fix-crash-on-NULL-parent.patch | 2 +- ...-set-HID-bit-in-streaming-endpoint-c.patch | 2 +- ...pci-Disable-Host-Memory-Buffer-usage.patch | 6 +- ...0692-cgroup-Add-cgroup_enable-option.patch | 2 +- ...-announce-support-for-SER_RS485_RTS_.patch | 2 +- ...bugfs-node-to-keep-track-of-requests.patch | 4 +- ...-to-Intel-scheme-for-calculating-U1-.patch | 6 +- mihomo/go.mod | 2 +- mihomo/go.sum | 4 +- nodepass/docs/en/api.md | 1 + nodepass/docs/en/configuration.md | 39 ++ nodepass/docs/zh/api.md | 1 + nodepass/docs/zh/configuration.md | 39 ++ nodepass/go.mod | 2 +- nodepass/go.sum | 4 +- nodepass/internal/client.go | 9 +- nodepass/internal/common.go | 177 ++++++-- nodepass/internal/master.go | 72 ++-- nodepass/internal/server.go | 15 +- openwrt-packages/luci-lib-taskd/Makefile | 2 +- .../luci-static/resources/tasks/tasks.js | 4 +- .../luasrc/controller/passwall.lua | 61 ++- .../model/cbi/passwall/client/node_config.lua | 13 + .../model/cbi/passwall/client/node_list.lua | 215 ---------- .../cbi/passwall/client/node_subscribe.lua | 2 +- .../view/passwall/node_list/link_add_node.htm | 7 +- .../view/passwall/node_list/node_list.htm | 390 +++++++++++++---- .../luci-app-passwall/po/zh-cn/passwall.po | 6 + .../root/etc/uci-defaults/luci-passwall | 5 +- .../root/usr/share/passwall/app.sh | 2 +- .../root/usr/share/passwall/iptables.sh | 28 +- .../root/usr/share/passwall/nftables.sh | 17 +- .../root/usr/share/passwall/subscribe.lua | 32 +- .../luasrc/controller/passwall2.lua | 60 ++- .../cbi/passwall2/client/node_config.lua | 13 + .../model/cbi/passwall2/client/node_list.lua | 208 ---------- .../cbi/passwall2/client/node_subscribe.lua | 2 +- .../passwall2/node_list/link_add_node.htm | 7 +- .../view/passwall2/node_list/node_list.htm | 392 +++++++++++++----- .../luci-app-passwall2/po/zh-cn/passwall2.po | 6 + .../root/etc/uci-defaults/luci-passwall2 | 4 +- .../root/usr/share/passwall2/app.sh | 2 +- .../root/usr/share/passwall2/iptables.sh | 34 +- .../root/usr/share/passwall2/nftables.sh | 21 +- .../root/usr/share/passwall2/subscribe.lua | 32 +- .../luasrc/controller/passwall.lua | 61 ++- .../model/cbi/passwall/client/node_config.lua | 13 + .../model/cbi/passwall/client/node_list.lua | 215 ---------- .../cbi/passwall/client/node_subscribe.lua | 2 +- .../view/passwall/node_list/link_add_node.htm | 7 +- .../view/passwall/node_list/node_list.htm | 390 +++++++++++++---- small/luci-app-passwall/po/zh-cn/passwall.po | 6 + .../root/etc/uci-defaults/luci-passwall | 5 +- .../root/usr/share/passwall/app.sh | 2 +- .../root/usr/share/passwall/iptables.sh | 28 +- .../root/usr/share/passwall/nftables.sh | 17 +- .../root/usr/share/passwall/subscribe.lua | 32 +- .../luasrc/controller/passwall2.lua | 60 ++- .../cbi/passwall2/client/node_config.lua | 13 + .../model/cbi/passwall2/client/node_list.lua | 208 ---------- .../cbi/passwall2/client/node_subscribe.lua | 2 +- .../passwall2/node_list/link_add_node.htm | 7 +- .../view/passwall2/node_list/node_list.htm | 392 +++++++++++++----- .../luci-app-passwall2/po/zh-cn/passwall2.po | 6 + .../root/etc/uci-defaults/luci-passwall2 | 4 +- .../root/usr/share/passwall2/app.sh | 2 +- .../root/usr/share/passwall2/iptables.sh | 34 +- .../root/usr/share/passwall2/nftables.sh | 21 +- .../root/usr/share/passwall2/subscribe.lua | 32 +- small/v2ray-geodata/Makefile | 4 +- v2rayn/v2rayN/Directory.Packages.props | 2 +- .../ServiceLib/Manager/CertPemManager.cs | 56 ++- .../ViewModels/AddServerViewModel.cs | 6 +- v2rayu/V2rayU/ConfigWindow.swift | 6 +- yt-dlp/yt_dlp/extractor/youtube/_base.py | 2 +- 99 files changed, 2200 insertions(+), 1709 deletions(-) diff --git a/.github/update.log b/.github/update.log index 1245cad4c2..500c7032ad 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1172,3 +1172,4 @@ Update On Sat Nov 1 19:37:41 CET 2025 Update On Sun Nov 2 19:34:13 CET 2025 Update On Mon Nov 3 19:37:13 CET 2025 Update On Tue Nov 4 19:40:23 CET 2025 +Update On Wed Nov 5 19:38:37 CET 2025 diff --git a/clash-meta/go.mod b/clash-meta/go.mod index 248325e2bb..ea42bce7d6 100644 --- a/clash-meta/go.mod +++ b/clash-meta/go.mod @@ -23,7 +23,7 @@ require ( github.com/metacubex/chacha v0.1.5 github.com/metacubex/fswatch v0.1.1 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 - github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a + github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 github.com/metacubex/randv2 v0.2.0 github.com/metacubex/restls-client-go v0.1.7 diff --git a/clash-meta/go.sum b/clash-meta/go.sum index 5069ad9a82..bfc1a8f524 100644 --- a/clash-meta/go.sum +++ b/clash-meta/go.sum @@ -108,8 +108,8 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ= github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU= -github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a h1:5vdk2pI71itLBT2mpyNExM1UKZ+2mG7MVC+ZARpRXmg= -github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be h1:Y7SigZIqfv/+RIA/D7R6EbB9p+brPRoGOM6zobSmRIM= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo= github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA= github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 h1:I1uvJl206/HbkzEAZpLgGkZgUveOZb+P+6oTUj7dN+o= diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index 9bceba8c7c..68fb1228e5 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -346,7 +346,7 @@ dependencies = [ "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", - "windows-sys 0.52.0", + "windows-sys 0.60.2", "wl-clipboard-rs", "x11rb", ] @@ -1688,7 +1688,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -2294,7 +2294,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2803,7 +2803,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -4922,7 +4922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.53.3", ] [[package]] @@ -6364,7 +6364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.45.0", + "windows-sys 0.61.2", ] [[package]] @@ -6424,9 +6424,9 @@ dependencies = [ [[package]] name = "oxc_allocator" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433214c659b860685d987ca25a523a544d35ebf87ee3658a942fd1c664cfa49b" +checksum = "71ef2dba21be1ce515378b2b7143eaa2a912f9e6ffe162ae20639d56f53d60e3" dependencies = [ "allocator-api2", "bumpalo", @@ -6437,9 +6437,9 @@ dependencies = [ [[package]] name = "oxc_ast" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e78ea25d23521092edcd509198635dd0bd96df7fb71349bcd8087bb8f6a615d" +checksum = "2fad9195311a1961bb6ef1de0ce6a52147bccea50b5a40423b7b44e8448ed4fc" dependencies = [ "bitflags 2.9.4", "oxc_allocator", @@ -6454,9 +6454,9 @@ dependencies = [ [[package]] name = "oxc_ast_macros" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f29bf83925451a7ebbd30d3ff449414cc230c9b63aba70487c2ca74ea1e3ed" +checksum = "7f03da6fac191c0817a32ae1a7dde27fd27d98732c61fcaeb55a99a4d543ba49" dependencies = [ "phf 0.13.1", "proc-macro2", @@ -6466,9 +6466,9 @@ dependencies = [ [[package]] name = "oxc_ast_visit" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808862f42c9331954cf187261d6a48dbf471ccbe60b6a35f6b1056c11f32e95b" +checksum = "b42fcdb162d247a0e9c1aa985b388f000eba19fb1ee1845b2ec0ddc595f95131" dependencies = [ "oxc_allocator", "oxc_ast", @@ -6478,15 +6478,15 @@ dependencies = [ [[package]] name = "oxc_data_structures" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd090988aa69c1e394f424289abb9bb1281448a072419ca556a07228ad36b854" +checksum = "c5f5171d7b8bc907a1b29e557d14f8478509a2154272d56db9ee8aed6bfe8dec" [[package]] name = "oxc_diagnostics" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b8a09558d38ee7f23faf0249cdb37b5b26f53a7375941f8636c41c661b283ce" +checksum = "8ef2bf6a713fd27bc65812d695bdfde3f8fcef735f00b861258518346642721b" dependencies = [ "cow-utils", "oxc-miette", @@ -6495,9 +6495,9 @@ dependencies = [ [[package]] name = "oxc_ecmascript" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0002ece1cc266aa6654913d39cf552b0cf501afce9d953b87c283dfcd307266" +checksum = "f908100cb2759dd2f42ca33d95ea158b8d78e2591b577757729fc9a4a4c63bc3" dependencies = [ "cow-utils", "num-bigint", @@ -6510,9 +6510,9 @@ dependencies = [ [[package]] name = "oxc_estree" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af85b24b7e10bf0ccb252f16d38492f51236c1ba146f62013993667cbf7fa649" +checksum = "5644d3399116ff3f0cfb81f9a790c4b8173b504ed52274ecc757b57f30098ad1" [[package]] name = "oxc_index" @@ -6526,9 +6526,9 @@ dependencies = [ [[package]] name = "oxc_parser" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb730ab93ff23bbc471ef7109f847afa709bb284dd52a5d3366283d724858158" +checksum = "e080498b7a4456a63111f9c65b4dd1b98147955347854b809b6ad4cc5d6a0c0a" dependencies = [ "bitflags 2.9.4", "cow-utils", @@ -6549,9 +6549,9 @@ dependencies = [ [[package]] name = "oxc_regular_expression" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27bafc3035e3b0fe555ae56f7bbc108a7ee520b0858250ba16d197e44ca83746" +checksum = "cb87ab0b072e1e97d8101cb1678204bc3873d84f13255ae5aa088f1b85f7a8e1" dependencies = [ "bitflags 2.9.4", "oxc_allocator", @@ -6565,9 +6565,9 @@ dependencies = [ [[package]] name = "oxc_span" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71243fe1ece27f71a6be5e2ab11d051792eeb578f3b056d7c9bbe82ec8043bf3" +checksum = "41422232cfd9915d31dbb76ba2e5ae212884cad232e37203bdcb15bd1466951d" dependencies = [ "compact_str", "oxc-miette", @@ -6578,9 +6578,9 @@ dependencies = [ [[package]] name = "oxc_syntax" -version = "0.95.0" +version = "0.96.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c99e555ed497111004a71fb2aa6f8fb90b0d3e2733aceeb035e24701d69634" +checksum = "9ea81736f2343df141c7d8de78a91d155be4f712dfa6cd1bdd9a8b4f0676f01f" dependencies = [ "bitflags 2.9.4", "cow-utils", @@ -7326,7 +7326,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -7880,7 +7880,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7893,7 +7893,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -9549,7 +9549,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix 1.0.8", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -11248,7 +11248,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/clash-nyanpasu/backend/tauri/Cargo.toml b/clash-nyanpasu/backend/tauri/Cargo.toml index 94448a3384..c1196371cb 100644 --- a/clash-nyanpasu/backend/tauri/Cargo.toml +++ b/clash-nyanpasu/backend/tauri/Cargo.toml @@ -172,12 +172,12 @@ display-info = "0.5.0" # should be removed after upgrading to tauri v2 # OXC (The Oxidation Compiler) # We use it to parse and transpile the old script profile to esm based script profile -oxc_parser = "0.95" -oxc_allocator = "0.95" -oxc_span = "0.95" -oxc_ast = "0.95" -oxc_syntax = "0.95" -oxc_ast_visit = "0.95" +oxc_parser = "0.96" +oxc_allocator = "0.96" +oxc_span = "0.96" +oxc_ast = "0.96" +oxc_syntax = "0.96" +oxc_ast_visit = "0.96" # Lua Integration mlua = { version = "0.11", features = [ diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index d27fcf3018..1b0299f3e5 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -42,14 +42,14 @@ "react-dom": "19.2.0", "react-error-boundary": "6.0.0", "react-fast-marquee": "1.6.5", - "react-hook-form-mui": "8.0.0", + "react-hook-form-mui": "8.2.0", "react-i18next": "15.7.4", "react-markdown": "10.1.0", "react-split-grid": "1.0.4", "react-use": "17.6.0", "rxjs": "7.8.2", "swr": "2.3.6", - "virtua": "0.45.3", + "virtua": "0.46.6", "vite-bundle-visualizer": "1.2.1" }, "devDependencies": { @@ -75,7 +75,7 @@ "@types/validator": "13.15.4", "@vitejs/plugin-legacy": "7.2.1", "@vitejs/plugin-react": "5.1.0", - "@vitejs/plugin-react-swc": "4.2.0", + "@vitejs/plugin-react-swc": "4.2.1", "change-case": "5.4.4", "clsx": "2.1.1", "core-js": "3.46.0", @@ -88,7 +88,7 @@ "unplugin-auto-import": "20.2.0", "unplugin-icons": "22.5.0", "validator": "13.15.20", - "vite": "7.1.12", + "vite": "7.2.0", "vite-plugin-html": "3.2.2", "vite-plugin-sass-dts": "1.3.34", "vite-plugin-svgr": "4.5.0", diff --git a/clash-nyanpasu/frontend/ui/package.json b/clash-nyanpasu/frontend/ui/package.json index 47ce69b169..84db35fbe3 100644 --- a/clash-nyanpasu/frontend/ui/package.json +++ b/clash-nyanpasu/frontend/ui/package.json @@ -15,7 +15,7 @@ "@mui/icons-material": "7.3.5", "@mui/lab": "7.0.0-beta.17", "@mui/material": "7.3.5", - "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-portal": "1.1.10", "@radix-ui/react-scroll-area": "1.2.10", "@tauri-apps/api": "2.8.0", "@types/d3": "7.4.3", @@ -30,7 +30,7 @@ "react-i18next": "15.7.4", "react-use": "17.6.0", "tailwindcss": "4.1.16", - "vite": "7.1.12", + "vite": "7.2.0", "vite-tsconfig-paths": "5.1.4" }, "devDependencies": { diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 74d08bf9e4..8aeb1f0f02 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,10 +2,10 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.15", - "mihomo_alpha": "alpha-fd39c2a", - "clash_rs": "v0.9.1", + "mihomo_alpha": "alpha-5a285ac", + "clash_rs": "v0.9.2", "clash_premium": "2023-09-05-gdcc8d87", - "clash_rs_alpha": "0.9.1-alpha+sha.cff16c6" + "clash_rs_alpha": "0.9.2-alpha+sha.b24d5a9" }, "arch_template": { "mihomo": { @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-11-03T22:21:13.590Z" + "updated_at": "2025-11-04T22:21:06.320Z" } diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index d1fd18b0a0..90b5d77819 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -309,8 +309,8 @@ importers: specifier: 1.6.5 version: 1.6.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-hook-form-mui: - specifier: 8.0.0 - version: 8.0.0(d8b8a0b598a4bb03193b0b1d4aca738a) + specifier: 8.2.0 + version: 8.2.0(d8b8a0b598a4bb03193b0b1d4aca738a) react-i18next: specifier: 15.7.4 version: 15.7.4(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3) @@ -330,8 +330,8 @@ importers: specifier: 2.3.6 version: 2.3.6(react@19.2.0) virtua: - specifier: 0.45.3 - version: 0.45.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.5) + specifier: 0.46.6 + version: 0.46.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.5) vite-bundle-visualizer: specifier: 1.2.1 version: 1.2.1(rollup@4.46.2) @@ -362,7 +362,7 @@ importers: version: 1.134.12(@tanstack/react-router@1.134.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.12)(@types/node@24.10.0)(csstype@3.1.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) '@tanstack/router-plugin': specifier: 1.134.12 - version: 1.134.12(@tanstack/react-router@1.134.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.134.12(@tanstack/react-router@1.134.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) '@tauri-apps/plugin-clipboard-manager': specifier: 2.3.0 version: 2.3.0 @@ -398,13 +398,13 @@ importers: version: 13.15.4 '@vitejs/plugin-legacy': specifier: 7.2.1 - version: 7.2.1(terser@5.36.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 7.2.1(terser@5.36.0)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitejs/plugin-react': specifier: 5.1.0 - version: 5.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.0(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitejs/plugin-react-swc': - specifier: 4.2.0 - version: 4.2.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + specifier: 4.2.1 + version: 4.2.1(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) change-case: specifier: 5.4.4 version: 5.4.4 @@ -442,20 +442,20 @@ importers: specifier: 13.15.20 version: 13.15.20 vite: - specifier: 7.1.12 - version: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + specifier: 7.2.0 + version: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) vite-plugin-html: specifier: 3.2.2 - version: 3.2.2(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.2.2(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) vite-plugin-sass-dts: specifier: 1.3.34 - version: 1.3.34(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.3.34(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) vite-plugin-svgr: specifier: 4.5.0 - version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) zod: specifier: 4.1.12 version: 4.1.12 @@ -475,8 +475,8 @@ importers: specifier: 7.3.5 version: 7.3.5(@emotion/react@11.14.0(@types/react@19.2.2)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@19.2.0))(@types/react@19.2.2)(react@19.2.0))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-portal': - specifier: 1.1.9 - version: 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 1.1.10 + version: 1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-scroll-area': specifier: 1.2.10 version: 1.2.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -491,7 +491,7 @@ importers: version: 19.2.2 '@vitejs/plugin-react': specifier: 5.1.0 - version: 5.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.0(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) ahooks: specifier: 3.9.6 version: 3.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -520,11 +520,11 @@ importers: specifier: 4.1.16 version: 4.1.16 vite: - specifier: 7.1.12 - version: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + specifier: 7.2.0 + version: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) devDependencies: '@emotion/react': specifier: 11.14.0 @@ -549,7 +549,7 @@ importers: version: 5.2.0(typescript@5.9.3) vite-plugin-dts: specifier: 4.5.4 - version: 4.5.4(@types/node@24.10.0)(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.5.4(@types/node@24.10.0)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) scripts: dependencies: @@ -2642,8 +2642,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + '@radix-ui/react-portal@1.1.10': + resolution: {integrity: sha512-4kY9IVa6+9nJPsYmngK5Uk2kUmZnv7ChhHAFeQ5oaj8jrR1bIi3xww8nH71pz1/Ve4d/cXO3YxT8eikt1B0a8w==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2681,6 +2681,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-primitive@2.1.4': + resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-scroll-area@1.2.10': resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} peerDependencies: @@ -2703,6 +2716,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-use-callback-ref@1.1.1': resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} peerDependencies: @@ -2724,6 +2746,9 @@ packages: '@rolldown/pluginutils@1.0.0-beta.43': resolution: {integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==} + '@rolldown/pluginutils@1.0.0-beta.46': + resolution: {integrity: sha512-xMNwJo/pHkEP/mhNVnW+zUiJDle6/hxrwO0mfSJuEVRbBfgrJFuUSRoZx/nYUw5pCjrysl9OkNXCkAdih8GCnA==} + '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -3809,8 +3834,8 @@ packages: terser: ^5.16.0 vite: ^7.0.0 - '@vitejs/plugin-react-swc@4.2.0': - resolution: {integrity: sha512-/tesahXD1qpkGC6FzMoFOJj0RyZdw9xLELOL+6jbElwmWfwOnIVy+IfpY+o9JfD9PKaR/Eyb6DNrvbXpuvA+8Q==} + '@vitejs/plugin-react-swc@4.2.1': + resolution: {integrity: sha512-SIZ/XxeS2naLw4L2vVvpTyujM2OY+Rf+y6nWETqfoBrZpI3SFdyNJof3nQ8HbLhXJ1Eh9e9c0JGYC8GYPhLkCw==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^4 || ^5 || ^6 || ^7 @@ -7256,8 +7281,8 @@ packages: react: '>= 16.8.0 || ^18.0.0' react-dom: '>= 16.8.0 || ^18.0.0' - react-hook-form-mui@8.0.0: - resolution: {integrity: sha512-NoqUMDhaWYUkjScVmmGUo8JRsA6jJCJLJtROKjJpA8whB8LDRbr/H6w6zU4txsj8VQtNNGcQQDZueq4Yu9i0iQ==} + react-hook-form-mui@8.2.0: + resolution: {integrity: sha512-hQ6tleg+VuHOk7+HUZLBlsztx5ZigslqgLKfcEdQDS0qUow1B6I7HG3uY2EvmPDdeFS1D4lU7pGxYKmnYpJwVg==} engines: {node: '>=14'} peerDependencies: '@mui/icons-material': '>= 5.x <8' @@ -8480,8 +8505,8 @@ packages: vfile@6.0.1: resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - virtua@0.45.3: - resolution: {integrity: sha512-+nW3VOwXhlte3m4jbS9gVMked/cZo95IKChH0qol+XUApQVZpPaLDGee1BC/rVng0tsMfxs0vJPEPEUAAfKpkw==} + virtua@0.46.6: + resolution: {integrity: sha512-yoUV8DHLj3GL7GPJ9gBGDY17JiMr5bt9wBj1giISpJBA2IwYmkexH+5lBExyOc+g9OZ7wpMKOjK8lQUWJh0G3A==} peerDependencies: react: '>=16.14.0' react-dom: '>=16.14.0' @@ -8541,8 +8566,8 @@ packages: vite: optional: true - vite@7.1.12: - resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} + vite@7.2.0: + resolution: {integrity: sha512-C/Naxf8H0pBx1PA4BdpT+c/5wdqI9ILMdwjSMILw7tVIh3JsxzZqdeTLmmdaoh5MYUEOyBnM9K3o0DzoZ/fe+w==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -11121,9 +11146,9 @@ snapshots: optionalDependencies: '@types/react': 19.2.2 - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-portal@1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) @@ -11150,6 +11175,15 @@ snapshots: '@types/react': 19.2.2 '@types/react-dom': 19.2.2(@types/react@19.2.2) + '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.2)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.2 + '@types/react-dom': 19.2.2(@types/react@19.2.2) + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@radix-ui/number': 1.1.1 @@ -11174,6 +11208,13 @@ snapshots: optionalDependencies: '@types/react': 19.2.2 + '@radix-ui/react-slot@1.2.4(@types/react@19.2.2)(react@19.2.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) + react: 19.2.0 + optionalDependencies: + '@types/react': 19.2.2 + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.2)(react@19.2.0)': dependencies: react: 19.2.0 @@ -11188,6 +11229,8 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.43': {} + '@rolldown/pluginutils@1.0.0-beta.46': {} + '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 @@ -11568,7 +11611,7 @@ snapshots: '@tanstack/router-devtools-core': 1.134.12(@tanstack/router-core@1.134.12)(@types/node@24.10.0)(csstype@3.1.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@tanstack/router-core' - '@types/node' @@ -11633,7 +11676,7 @@ snapshots: goober: 2.1.16(csstype@3.1.3) solid-js: 1.9.5 tiny-invariant: 1.3.3 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: csstype: 3.1.3 transitivePeerDependencies: @@ -11662,7 +11705,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.134.12(@tanstack/react-router@1.134.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/router-plugin@1.134.12(@tanstack/react-router@1.134.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) @@ -11680,7 +11723,7 @@ snapshots: zod: 3.25.76 optionalDependencies: '@tanstack/react-router': 1.134.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -12293,7 +12336,7 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.10.1': optional: true - '@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.0 '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.0) @@ -12308,19 +12351,19 @@ snapshots: regenerator-runtime: 0.14.1 systemjs: 6.15.1 terser: 5.36.0 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react-swc@4.2.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-react-swc@4.2.1(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@rolldown/pluginutils': 1.0.0-beta.43 + '@rolldown/pluginutils': 1.0.0-beta.46 '@swc/core': 1.13.5 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@5.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-react@5.1.0(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) @@ -12328,7 +12371,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.43 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -16241,7 +16284,7 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - react-hook-form-mui@8.0.0(d8b8a0b598a4bb03193b0b1d4aca738a): + react-hook-form-mui@8.2.0(d8b8a0b598a4bb03193b0b1d4aca738a): dependencies: '@mui/material': 7.3.5(@emotion/react@11.14.0(@types/react@19.2.2)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@19.2.0))(@types/react@19.2.2)(react@19.2.0))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 @@ -17662,7 +17705,7 @@ snapshots: unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - virtua@0.45.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.5): + virtua@0.46.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.5): optionalDependencies: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) @@ -17678,7 +17721,7 @@ snapshots: - rollup - supports-color - vite-plugin-dts@4.5.4(@types/node@24.10.0)(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-dts@4.5.4(@types/node@24.10.0)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@microsoft/api-extractor': 7.51.0(@types/node@24.10.0) '@rollup/pluginutils': 5.1.4(rollup@4.46.2) @@ -17691,13 +17734,13 @@ snapshots: magic-string: 0.30.17 typescript: 5.9.3 optionalDependencies: - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-html@3.2.2(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-html@3.2.2(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@rollup/pluginutils': 4.2.1 colorette: 2.0.20 @@ -17711,39 +17754,39 @@ snapshots: html-minifier-terser: 6.1.0 node-html-parser: 5.4.2 pathe: 0.2.0 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-sass-dts@1.3.34(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-sass-dts@1.3.34(postcss@8.5.6)(prettier@3.6.2)(sass-embedded@1.93.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: postcss: 8.5.6 postcss-js: 4.0.1(postcss@8.5.6) prettier: 3.6.2 sass-embedded: 1.93.3 - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: '@rollup/pluginutils': 5.2.0(rollup@4.46.2) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - rollup - supports-color - typescript - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: debug: 4.3.7 globrex: 0.1.2 tsconfck: 3.0.3(typescript@5.9.3) optionalDependencies: - vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1): + vite@7.2.0(@types/node@24.10.0)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.0 fdir: 6.5.0(picomatch@4.0.3) diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0018-arm64-setup-Fix-build-warning.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0018-arm64-setup-Fix-build-warning.patch index 0867cda6de..cca6e76064 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0018-arm64-setup-Fix-build-warning.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0018-arm64-setup-Fix-build-warning.patch @@ -13,7 +13,7 @@ Signed-off-by: Maxime Ripard @@ -214,9 +214,9 @@ static void __init request_standard_reso size_t res_size; - kernel_code.start = __pa_symbol(_stext); + kernel_code.start = __pa_symbol(_text); - kernel_code.end = __pa_symbol(__init_begin - 1); + kernel_code.end = __pa_symbol(__init_begin) - 1; kernel_data.start = __pa_symbol(_sdata); diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0073-ASoC-Add-support-for-all-the-downstream-rpi-sound-ca.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0073-ASoC-Add-support-for-all-the-downstream-rpi-sound-ca.patch index 59105068c1..c6ce4dd6db 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0073-ASoC-Add-support-for-all-the-downstream-rpi-sound-ca.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0073-ASoC-Add-support-for-all-the-downstream-rpi-sound-ca.patch @@ -18608,7 +18608,7 @@ Signed-off-by: j-schambacher } --- a/sound/usb/card.c +++ b/sound/usb/card.c -@@ -869,8 +869,14 @@ static int usb_audio_probe(struct usb_in +@@ -875,8 +875,14 @@ static int usb_audio_probe(struct usb_in if (ignore_ctl_error) chip->quirk_flags |= QUIRK_FLAG_IGNORE_CTL_ERROR; @@ -18626,7 +18626,7 @@ Signed-off-by: j-schambacher * For devices with more than one control interface, we assume the --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c -@@ -2360,6 +2360,8 @@ static const struct usb_audio_quirk_flag +@@ -2378,6 +2378,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */ QUIRK_FLAG_ALIGN_TRANSFER), diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0094-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0094-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch index 0d6a293ffd..9d9b3dcb50 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0094-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0094-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch @@ -37,7 +37,7 @@ Signed-off-by: Dave Stevenson static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) { u32 *buf; -@@ -3444,8 +3453,14 @@ static int lan78xx_bind(struct lan78xx_n +@@ -3464,8 +3473,14 @@ static int lan78xx_bind(struct lan78xx_n if (DEFAULT_RX_CSUM_ENABLE) dev->net->features |= NETIF_F_RXCSUM; diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0096-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0096-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch index 9eb0f87332..79881ca14c 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0096-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0096-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch @@ -28,7 +28,7 @@ See: https://github.com/raspberrypi/linux/issues/2447 static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) { u32 *buf; -@@ -4428,7 +4433,13 @@ static int lan78xx_probe(struct usb_inte +@@ -4448,7 +4453,13 @@ static int lan78xx_probe(struct usb_inte if (ret < 0) goto out4; diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0098-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0098-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch index d430674c28..de734ca0c7 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0098-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0098-Patching-lan78xx-for-SOF_TIMESTAMPING_TX_SOFTWARE-su.patch @@ -16,4 +16,4 @@ Subject: [PATCH] Patching lan78xx for SOF_TIMESTAMPING_TX_SOFTWARE support + .get_ts_info = ethtool_op_get_ts_info, }; - static void lan78xx_init_mac_address(struct lan78xx_net *dev) + static int lan78xx_init_mac_address(struct lan78xx_net *dev) diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0099-lan78xx-Enable-LEDs-and-auto-negotiation.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0099-lan78xx-Enable-LEDs-and-auto-negotiation.patch index c55ffd0494..4137adb1fb 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0099-lan78xx-Enable-LEDs-and-auto-negotiation.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0099-lan78xx-Enable-LEDs-and-auto-negotiation.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2897,6 +2897,11 @@ static int lan78xx_reset(struct lan78xx_ +@@ -2915,6 +2915,11 @@ static int lan78xx_reset(struct lan78xx_ int ret; u32 buf; u8 sig; @@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell ret = lan78xx_read_reg(dev, HW_CFG, &buf); if (ret < 0) -@@ -2963,6 +2968,10 @@ static int lan78xx_reset(struct lan78xx_ +@@ -2983,6 +2988,10 @@ static int lan78xx_reset(struct lan78xx_ buf |= HW_CFG_CLK125_EN_; buf |= HW_CFG_REFCLK25_EN_; @@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell ret = lan78xx_write_reg(dev, HW_CFG, buf); if (ret < 0) return ret; -@@ -3065,6 +3074,9 @@ static int lan78xx_reset(struct lan78xx_ +@@ -3085,6 +3094,9 @@ static int lan78xx_reset(struct lan78xx_ buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; } } diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0125-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0125-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch index 1860bf1737..0491be4369 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0125-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0125-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch @@ -14,7 +14,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c -@@ -1519,6 +1519,109 @@ static int xhci_check_ep0_maxpacket(stru +@@ -1515,6 +1515,109 @@ static int xhci_check_ep0_maxpacket(stru } /* @@ -124,7 +124,7 @@ Signed-off-by: Jonathan Bell * non-error returns are a promise to giveback() the urb later * we drop ownership so next owner (or urb unlink) can get it */ -@@ -5390,6 +5493,7 @@ static const struct hc_driver xhci_hc_dr +@@ -5386,6 +5489,7 @@ static const struct hc_driver xhci_hc_dr .endpoint_reset = xhci_endpoint_reset, .check_bandwidth = xhci_check_bandwidth, .reset_bandwidth = xhci_reset_bandwidth, diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0127-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0127-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch index 1ac575a2ce..e2f7caeaf6 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0127-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0127-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch @@ -19,7 +19,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c -@@ -1608,7 +1608,7 @@ static void xhci_fixup_endpoint(struct u +@@ -1604,7 +1604,7 @@ static void xhci_fixup_endpoint(struct u return; } ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0322-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0322-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch index d5a21169bd..81e8d31c1b 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0322-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0322-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch @@ -20,7 +20,7 @@ Signed-off-by: Phil Elwell --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c -@@ -4921,6 +4921,7 @@ static const struct { +@@ -4930,6 +4930,7 @@ static const struct { */ static int hci_dev_setup_sync(struct hci_dev *hdev) { @@ -28,7 +28,7 @@ Signed-off-by: Phil Elwell int ret = 0; bool invalid_bdaddr; size_t i; -@@ -4949,7 +4950,8 @@ static int hci_dev_setup_sync(struct hci +@@ -4958,7 +4959,8 @@ static int hci_dev_setup_sync(struct hci test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); if (!ret) { if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) && diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0331-serial-sc16is7xx-Read-modem-line-state-at-startup.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0331-serial-sc16is7xx-Read-modem-line-state-at-startup.patch index 57945f6e8b..686aba0ecf 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0331-serial-sc16is7xx-Read-modem-line-state-at-startup.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0331-serial-sc16is7xx-Read-modem-line-state-at-startup.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c -@@ -1206,6 +1206,9 @@ static int sc16is7xx_startup(struct uart +@@ -1196,6 +1196,9 @@ static int sc16is7xx_startup(struct uart SC16IS7XX_IER_MSI_BIT; sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0333-xhci-quirks-add-link-TRB-quirk-for-VL805.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0333-xhci-quirks-add-link-TRB-quirk-for-VL805.patch index f283308934..fad1aafc0f 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0333-xhci-quirks-add-link-TRB-quirk-for-VL805.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0333-xhci-quirks-add-link-TRB-quirk-for-VL805.patch @@ -53,7 +53,7 @@ Signed-off-by: Jonathan Bell if (addr == 0) { --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1628,6 +1628,9 @@ struct xhci_hcd { +@@ -1631,6 +1631,9 @@ struct xhci_hcd { #define XHCI_ETRON_HOST BIT_ULL(49) #define XHCI_LIMIT_ENDPOINT_INTERVAL_9 BIT_ULL(50) diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0334-usb-xhci-add-VLI_SS_BULK_OUT_BUG-quirk.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0334-usb-xhci-add-VLI_SS_BULK_OUT_BUG-quirk.patch index 4e1c1bd76b..56708d6bcb 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0334-usb-xhci-add-VLI_SS_BULK_OUT_BUG-quirk.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0334-usb-xhci-add-VLI_SS_BULK_OUT_BUG-quirk.patch @@ -34,7 +34,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c -@@ -1397,6 +1397,7 @@ int xhci_endpoint_init(struct xhci_hcd * +@@ -1387,6 +1387,7 @@ int xhci_endpoint_init(struct xhci_hcd * unsigned int ep_index; struct xhci_ep_ctx *ep_ctx; struct xhci_ring *ep_ring; @@ -42,7 +42,7 @@ Signed-off-by: Jonathan Bell unsigned int max_packet; enum xhci_ring_type ring_type; u32 max_esit_payload; -@@ -1406,6 +1407,8 @@ int xhci_endpoint_init(struct xhci_hcd * +@@ -1396,6 +1397,8 @@ int xhci_endpoint_init(struct xhci_hcd * unsigned int mult; unsigned int avg_trb_len; unsigned int err_count = 0; @@ -51,7 +51,7 @@ Signed-off-by: Jonathan Bell ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); -@@ -1441,9 +1444,35 @@ int xhci_endpoint_init(struct xhci_hcd * +@@ -1431,9 +1434,35 @@ int xhci_endpoint_init(struct xhci_hcd * mult = xhci_get_endpoint_mult(udev, ep); max_packet = usb_endpoint_maxp(&ep->desc); @@ -100,7 +100,7 @@ Signed-off-by: Jonathan Bell if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1630,6 +1630,7 @@ struct xhci_hcd { +@@ -1633,6 +1633,7 @@ struct xhci_hcd { /* Downstream VLI fixes */ #define XHCI_AVOID_DQ_ON_LINK BIT_ULL(56) diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0335-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0335-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch index c1731fb1df..9abbcd0bae 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0335-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0335-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch @@ -75,7 +75,7 @@ Signed-off-by: Jonathan Bell if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -3664,6 +3664,48 @@ static int xhci_align_td(struct xhci_hcd +@@ -3661,6 +3661,48 @@ static int xhci_align_td(struct xhci_hcd return 1; } @@ -124,7 +124,7 @@ Signed-off-by: Jonathan Bell /* This is very similar to what ehci-q.c qtd_fill() does */ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index) -@@ -3818,6 +3860,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * +@@ -3815,6 +3857,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd * } check_trb_math(urb, enqd_len); @@ -133,7 +133,7 @@ Signed-off-by: Jonathan Bell giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, start_cycle, start_trb); return 0; -@@ -3966,6 +4010,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * +@@ -3963,6 +4007,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * /* Event on completion */ field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state); @@ -144,7 +144,7 @@ Signed-off-by: Jonathan Bell return 0; --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1631,6 +1631,7 @@ struct xhci_hcd { +@@ -1634,6 +1634,7 @@ struct xhci_hcd { /* Downstream VLI fixes */ #define XHCI_AVOID_DQ_ON_LINK BIT_ULL(56) #define XHCI_VLI_SS_BULK_OUT_BUG BIT_ULL(57) diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0401-xhci-Use-more-event-ring-segment-table-entries.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0401-xhci-Use-more-event-ring-segment-table-entries.patch index 6baba3b443..f74985e433 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0401-xhci-Use-more-event-ring-segment-table-entries.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0401-xhci-Use-more-event-ring-segment-table-entries.patch @@ -21,7 +21,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h -@@ -1395,7 +1395,7 @@ struct urb_priv { +@@ -1398,7 +1398,7 @@ struct urb_priv { }; /* Number of Event Ring segments to allocate, when amount is not specified. (spec allows 32k) */ diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0476-lan78xx-Read-initial-EEE-status-from-DT.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0476-lan78xx-Read-initial-EEE-status-from-DT.patch index 945e0a5b15..1c2ec17d50 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0476-lan78xx-Read-initial-EEE-status-from-DT.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0476-lan78xx-Read-initial-EEE-status-from-DT.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2422,7 +2422,26 @@ static int lan78xx_phy_init(struct lan78 +@@ -2440,7 +2440,26 @@ static int lan78xx_phy_init(struct lan78 mii_adv_to_linkmode_adv_t(fc, mii_adv); linkmode_or(phydev->advertising, fc, phydev->advertising); diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0502-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0502-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch index 2b1d523594..cb98eb72fb 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0502-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0502-Bluetooth-hci_sync-Fix-crash-on-NULL-parent.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c -@@ -4921,7 +4921,8 @@ static const struct { +@@ -4930,7 +4930,8 @@ static const struct { */ static int hci_dev_setup_sync(struct hci_dev *hdev) { diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0534-drivers-usb-xhci-set-HID-bit-in-streaming-endpoint-c.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0534-drivers-usb-xhci-set-HID-bit-in-streaming-endpoint-c.patch index 9a052443c0..9d0a6e2055 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0534-drivers-usb-xhci-set-HID-bit-in-streaming-endpoint-c.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0534-drivers-usb-xhci-set-HID-bit-in-streaming-endpoint-c.patch @@ -28,7 +28,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c -@@ -715,6 +715,14 @@ void xhci_setup_streams_ep_input_ctx(str +@@ -705,6 +705,14 @@ void xhci_setup_streams_ep_input_ctx(str ep_ctx->ep_info &= cpu_to_le32(~EP_MAXPSTREAMS_MASK); ep_ctx->ep_info |= cpu_to_le32(EP_MAXPSTREAMS(max_primary_streams) | EP_HAS_LSA); diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0685-nvme-pci-Disable-Host-Memory-Buffer-usage.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0685-nvme-pci-Disable-Host-Memory-Buffer-usage.patch index 5ae8f6c966..a299c6c57e 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0685-nvme-pci-Disable-Host-Memory-Buffer-usage.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0685-nvme-pci-Disable-Host-Memory-Buffer-usage.patch @@ -18,7 +18,7 @@ Signed-off-by: Phil Elwell --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c -@@ -2103,6 +2103,7 @@ static void nvme_free_host_mem(struct nv +@@ -2106,6 +2106,7 @@ static void nvme_free_host_mem(struct nv dev->nr_host_mem_descs = 0; } @@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred, u32 chunk_size) { -@@ -2171,9 +2172,11 @@ out: +@@ -2174,9 +2175,11 @@ out: dev->host_mem_descs = NULL; return -ENOMEM; } @@ -38,7 +38,7 @@ Signed-off-by: Phil Elwell u64 min_chunk = min_t(u64, preferred, PAGE_SIZE * MAX_ORDER_NR_PAGES); u64 hmminds = max_t(u32, dev->ctrl.hmminds * 4096, PAGE_SIZE * 2); u64 chunk_size; -@@ -2186,6 +2189,7 @@ static int nvme_alloc_host_mem(struct nv +@@ -2189,6 +2192,7 @@ static int nvme_alloc_host_mem(struct nv nvme_free_host_mem(dev); } } diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0692-cgroup-Add-cgroup_enable-option.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0692-cgroup-Add-cgroup_enable-option.patch index 9ea92a5f32..d44e050e02 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0692-cgroup-Add-cgroup_enable-option.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0692-cgroup-Add-cgroup_enable-option.patch @@ -17,7 +17,7 @@ Signed-off-by: Phil Elwell --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c -@@ -6887,6 +6887,39 @@ static int __init cgroup_disable(char *s +@@ -6916,6 +6916,39 @@ static int __init cgroup_disable(char *s } __setup("cgroup_disable=", cgroup_disable); diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0702-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0702-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch index 5de1b1c4ac..7a8b37a00d 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0702-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0702-serial-sc16is7xx-announce-support-for-SER_RS485_RTS_.patch @@ -31,7 +31,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c -@@ -1478,7 +1478,7 @@ static int sc16is7xx_setup_mctrl_ports(s +@@ -1468,7 +1468,7 @@ static int sc16is7xx_setup_mctrl_ports(s } static const struct serial_rs485 sc16is7xx_rs485_supported = { diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0830-media-mc-add-debugfs-node-to-keep-track-of-requests.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0830-media-mc-add-debugfs-node-to-keep-track-of-requests.patch index 0e31e290e7..7ad80a032c 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0830-media-mc-add-debugfs-node-to-keep-track-of-requests.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0830-media-mc-add-debugfs-node-to-keep-track-of-requests.patch @@ -88,7 +88,7 @@ Signed-off-by: Hans Verkuil /* Called when the last user of the media device exits. */ static void media_devnode_release(struct device *cd) { -@@ -236,6 +239,7 @@ int __must_check media_devnode_register( +@@ -231,6 +234,7 @@ int __must_check media_devnode_register( if (devnode->parent) devnode->dev.parent = devnode->parent; dev_set_name(&devnode->dev, "media%d", devnode->minor); @@ -96,7 +96,7 @@ Signed-off-by: Hans Verkuil device_initialize(&devnode->dev); /* Part 2: Initialize the character device */ -@@ -313,6 +317,7 @@ static int __init media_devnode_init(voi +@@ -309,6 +313,7 @@ static int __init media_devnode_init(voi static void __exit media_devnode_exit(void) { diff --git a/lede/target/linux/bcm27xx/patches-6.12/950-0950-usb-xhci-default-to-Intel-scheme-for-calculating-U1-.patch b/lede/target/linux/bcm27xx/patches-6.12/950-0950-usb-xhci-default-to-Intel-scheme-for-calculating-U1-.patch index 06b91a6ce6..33f8ca71ad 100644 --- a/lede/target/linux/bcm27xx/patches-6.12/950-0950-usb-xhci-default-to-Intel-scheme-for-calculating-U1-.patch +++ b/lede/target/linux/bcm27xx/patches-6.12/950-0950-usb-xhci-default-to-Intel-scheme-for-calculating-U1-.patch @@ -39,8 +39,8 @@ Signed-off-by: Jonathan Bell + static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring) { - struct xhci_segment *seg = ring->first_seg; -@@ -4795,7 +4799,7 @@ static u16 xhci_calculate_u1_timeout(str + struct xhci_segment *seg; +@@ -4791,7 +4795,7 @@ static u16 xhci_calculate_u1_timeout(str } } @@ -49,7 +49,7 @@ Signed-off-by: Jonathan Bell timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); else timeout_ns = udev->u1_params.sel; -@@ -4859,7 +4863,7 @@ static u16 xhci_calculate_u2_timeout(str +@@ -4855,7 +4859,7 @@ static u16 xhci_calculate_u2_timeout(str } } diff --git a/mihomo/go.mod b/mihomo/go.mod index 248325e2bb..ea42bce7d6 100644 --- a/mihomo/go.mod +++ b/mihomo/go.mod @@ -23,7 +23,7 @@ require ( github.com/metacubex/chacha v0.1.5 github.com/metacubex/fswatch v0.1.1 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 - github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a + github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 github.com/metacubex/randv2 v0.2.0 github.com/metacubex/restls-client-go v0.1.7 diff --git a/mihomo/go.sum b/mihomo/go.sum index 5069ad9a82..bfc1a8f524 100644 --- a/mihomo/go.sum +++ b/mihomo/go.sum @@ -108,8 +108,8 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ= github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU= -github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a h1:5vdk2pI71itLBT2mpyNExM1UKZ+2mG7MVC+ZARpRXmg= -github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be h1:Y7SigZIqfv/+RIA/D7R6EbB9p+brPRoGOM6zobSmRIM= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo= github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA= github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 h1:I1uvJl206/HbkzEAZpLgGkZgUveOZb+P+6oTUj7dN+o= diff --git a/nodepass/docs/en/api.md b/nodepass/docs/en/api.md index c3cf7964d3..5d71c85163 100644 --- a/nodepass/docs/en/api.md +++ b/nodepass/docs/en/api.md @@ -1582,4 +1582,5 @@ Examples: | `rate` | Bandwidth rate limit | Integer (Mbps), 0=unlimited | `0` | Both | | `slot` | Connection slot count | Integer (1-65536) | `65536` | Both | | `proxy` | PROXY protocol support | `0`(disabled), `1`(enabled) | `0` | Both | +| `notcp` | TCP support control | `0`(enabled), `1`(disabled) | `0` | Both | | `noudp` | UDP support control | `0`(enabled), `1`(disabled) | `0` | Both | \ No newline at end of file diff --git a/nodepass/docs/en/configuration.md b/nodepass/docs/en/configuration.md index fdd5ec1b0c..f6c3c8883c 100644 --- a/nodepass/docs/en/configuration.md +++ b/nodepass/docs/en/configuration.md @@ -262,6 +262,43 @@ nodepass "server://0.0.0.0:10101/0.0.0.0:8080?log=info&tls=1&proxy=1&rate=100" - The header format follows the HAProxy PROXY protocol v1 specification - If the target service doesn't support PROXY protocol, connections may fail or behave unexpectedly +## TCP Support Control + +NodePass supports TCP traffic tunneling by default. The `notcp` parameter allows you to disable TCP support when only UDP traffic needs to be handled, which can reduce resource usage and simplify configuration. + +- `notcp`: TCP support control (default: 0) + - Value 0: TCP support enabled - both TCP and UDP traffic will be tunneled + - Value 1: TCP support disabled - only UDP traffic will be tunneled, TCP connections are ignored + - Applies to both client and server modes + - When disabled, TCP-related resources (buffers, connections, sessions) are not allocated + +Example: +```bash +# Enable TCP support (default behavior) +nodepass "server://0.0.0.0:10101/0.0.0.0:8080?notcp=0" + +# Disable TCP support for UDP-only scenarios +nodepass "server://0.0.0.0:10101/0.0.0.0:8080?notcp=1" + +# Client with TCP disabled +nodepass "client://server.example.com:10101/127.0.0.1:8080?notcp=1" + +# Combined with other parameters +nodepass "server://0.0.0.0:10101/0.0.0.0:8080?log=info&tls=1¬cp=1" +``` + +**TCP Support Control Use Cases:** +- **UDP-Only Services**: Disable TCP when tunneling only UDP-based applications +- **Resource Optimization**: Reduce memory and CPU usage by avoiding TCP processing overhead +- **Security**: Prevent TCP-based attacks or unwanted traffic in restricted environments +- **Simplified Configuration**: Easier setup when TCP tunneling is not required +- **Network Isolation**: Isolate TCP and UDP traffic handling for better control + +**Important Notes:** +- When TCP is disabled, any TCP connections sent to the tunnel will be silently dropped +- Existing TCP sessions will be terminated when switching to notcp=1 +- TCP buffer pools and session management are disabled when notcp=1 + ## UDP Support Control NodePass supports UDP traffic tunneling in addition to TCP. The `noudp` parameter allows you to disable UDP support when only TCP traffic needs to be handled, which can reduce resource usage and simplify configuration. @@ -373,6 +410,7 @@ NodePass allows flexible configuration via URL query parameters. The following t | `rate` | Bandwidth rate limit | `0` | O | O | X | | `slot` | Maximum connection limit | `65536` | O | O | X | | `proxy` | PROXY protocol support| `0` | O | O | X | +| `notcp` | TCP support control | `0` | O | O | X | | `noudp` | UDP support control | `0` | O | O | X | - O: Parameter is valid and recommended for configuration @@ -383,6 +421,7 @@ NodePass allows flexible configuration via URL query parameters. The following t - For client/server dual-end handshake modes, adjust connection pool capacity (`min`, `max`) based on traffic and resource constraints for optimal performance. - Use run mode control (`mode`) when automatic detection doesn't match your deployment requirements or for consistent behavior across environments. - Configure rate limiting (`rate`) to control bandwidth usage and prevent network congestion in shared environments. +- Set `notcp=1` when only UDP traffic needs to be tunneled to reduce resource usage and simplify configuration. - Set `noudp=1` when only TCP traffic needs to be tunneled to reduce resource usage and simplify configuration. - Log level (`log`) can be set in all modes for easier operations and troubleshooting. diff --git a/nodepass/docs/zh/api.md b/nodepass/docs/zh/api.md index 60ecae66ab..6ae28b06de 100644 --- a/nodepass/docs/zh/api.md +++ b/nodepass/docs/zh/api.md @@ -1582,4 +1582,5 @@ client://:/:? | `rate` | 带宽速率限制 | 整数 (Mbps), 0=无限制 | `0` | 两者 | | `slot` | 连接槽位数 | 整数 (1-65536) | `65536` | 两者 | | `proxy` | PROXY协议支持 | `0`(禁用), `1`(启用) | `0` | 两者 | +| `notcp` | TCP支持控制 | `0`(启用), `1`(禁用) | `0` | 两者 | | `noudp` | UDP支持控制 | `0`(启用), `1`(禁用) | `0` | 两者 | \ No newline at end of file diff --git a/nodepass/docs/zh/configuration.md b/nodepass/docs/zh/configuration.md index f09855a341..904ac6ff0c 100644 --- a/nodepass/docs/zh/configuration.md +++ b/nodepass/docs/zh/configuration.md @@ -262,6 +262,43 @@ nodepass "server://0.0.0.0:10101/0.0.0.0:8080?log=info&tls=1&proxy=1&rate=100" - 头部格式遵循HAProxy PROXY协议v1规范 - 如果目标服务不支持PROXY协议,将导致连接失败 +## TCP支持控制 + +NodePass默认支持TCP流量隧道。`notcp`参数允许您在只需要处理UDP流量时禁用TCP支持,这样可以减少资源使用并简化配置。 + +- `notcp`: TCP支持控制(默认: 0) + - 值为0:启用TCP支持 - TCP和UDP流量都将被隧道传输 + - 值为1:禁用TCP支持 - 仅UDP流量将被隧道传输,TCP连接被忽略 + - 适用于客户端和服务器模式 + - 禁用时,不分配TCP相关资源(缓冲区、连接、会话) + +示例: +```bash +# 启用TCP支持(默认行为) +nodepass "server://0.0.0.0:10101/0.0.0.0:8080?notcp=0" + +# 禁用TCP支持,仅处理UDP场景 +nodepass "server://0.0.0.0:10101/0.0.0.0:8080?notcp=1" + +# 客户端禁用TCP +nodepass "client://server.example.com:10101/127.0.0.1:8080?notcp=1" + +# 与其他参数结合 +nodepass "server://0.0.0.0:10101/0.0.0.0:8080?log=info&tls=1¬cp=1" +``` + +**TCP支持控制使用场景:** +- **仅UDP服务**:仅需要隧道传输UDP应用时禁用TCP +- **资源优化**:通过避免TCP处理开销减少内存和CPU使用 +- **安全性**:防止受限环境中的TCP攻击或不需要的流量 +- **简化配置**:不需要TCP隧道时更容易设置 +- **网络隔离**:更好地控制TCP和UDP流量处理 + +**重要说明:** +- 禁用TCP时,发送到隧道的任何TCP连接将被静默丢弃 +- 切换到notcp=1时,现有的TCP会话将被终止 +- 当notcp=1时,TCP缓冲池和会话管理被禁用 + ## UDP支持控制 除了TCP之外,NodePass还支持UDP流量隧道。`noudp`参数允许您在只需要处理TCP流量时禁用UDP支持,这样可以减少资源使用并简化配置。 @@ -373,6 +410,7 @@ NodePass支持通过URL查询参数进行灵活配置,不同参数在 server | `rate` | 带宽速率限制 | `0` | O | O | X | | `slot` | 最大连接数限制 | `65536` | O | O | X | | `proxy` | PROXY协议支持 | `0` | O | O | X | +| `notcp` | TCP支持控制 | `0` | O | O | X | | `noudp` | UDP支持控制 | `0` | O | O | X | - O:参数有效,推荐根据实际场景配置 @@ -383,6 +421,7 @@ NodePass支持通过URL查询参数进行灵活配置,不同参数在 server - client/server 双端握手模式建议根据流量和资源情况调整连接池容量(min/max),优化性能。 - 当自动检测不符合部署需求时或需要跨环境一致行为时,使用运行模式控制(mode)。 - 配置速率限制(rate)以控制带宽使用,防止共享环境中的网络拥塞。 +- 仅需要隧道传输UDP流量时设置`notcp=1`,以减少资源使用并简化配置。 - 仅需要隧道传输TCP流量时设置`noudp=1`,以减少资源使用并简化配置。 - 日志级别(log)可在所有模式下灵活调整,便于运维和排查。 diff --git a/nodepass/go.mod b/nodepass/go.mod index c1575a2aeb..e40a6acfe3 100644 --- a/nodepass/go.mod +++ b/nodepass/go.mod @@ -6,5 +6,5 @@ require ( github.com/NodePassProject/cert v1.0.1 github.com/NodePassProject/conn v1.0.16 github.com/NodePassProject/logs v1.0.3 - github.com/NodePassProject/pool v1.0.48 + github.com/NodePassProject/pool v1.0.49 ) diff --git a/nodepass/go.sum b/nodepass/go.sum index ab3f52ba9c..bf2696b3f1 100644 --- a/nodepass/go.sum +++ b/nodepass/go.sum @@ -4,5 +4,5 @@ github.com/NodePassProject/conn v1.0.16 h1:ojHfyBveZMcyOikdUs1SOW4yKp92NOBnNhfNe github.com/NodePassProject/conn v1.0.16/go.mod h1:xfQ7ZLUxrtdLsljGHYYCToW+Hdg6DAbmL1Cs94n5h6E= github.com/NodePassProject/logs v1.0.3 h1:CDUZVQ477vmmFQHazrQCWM0gJPNINm0C2N3FzC4jVyw= github.com/NodePassProject/logs v1.0.3/go.mod h1:TwtPXOzLtb8iH+fdduQjEEywICXivsM39cy9AinMSks= -github.com/NodePassProject/pool v1.0.48 h1:99pCHQYtmH5sVIB0vY+KbV4zyWSH6ptHgkKtxDnjpqQ= -github.com/NodePassProject/pool v1.0.48/go.mod h1:joQFk1oocg56QpJ1QK/2g5Jv/AyqYUQgPXMG1gWe8iA= +github.com/NodePassProject/pool v1.0.49 h1:gktVmE+GsQ0/C0MF8qgRraR7eS3na4k0QrQfR6o4fkM= +github.com/NodePassProject/pool v1.0.49/go.mod h1:joQFk1oocg56QpJ1QK/2g5Jv/AyqYUQgPXMG1gWe8iA= diff --git a/nodepass/internal/client.go b/nodepass/internal/client.go index 31ab6f9454..12ccee61e8 100644 --- a/nodepass/internal/client.go +++ b/nodepass/internal/client.go @@ -45,7 +45,6 @@ func NewClient(parsedURL *url.URL, logger *logs.Logger) (*Client, error) { return &buf }, }, - cleanURL: &url.URL{Scheme: "np", Fragment: "c"}, flushURL: &url.URL{Scheme: "np", Fragment: "f"}, pingURL: &url.URL{Scheme: "np", Fragment: "i"}, pongURL: &url.URL{Scheme: "np", Fragment: "o"}, @@ -62,9 +61,9 @@ func NewClient(parsedURL *url.URL, logger *logs.Logger) (*Client, error) { // Run 管理客户端生命周期 func (c *Client) Run() { logInfo := func(prefix string) { - c.logger.Info("%v: client://%v@%v/%v?min=%v&mode=%v&read=%v&rate=%v&slot=%v&proxy=%v&noudp=%v", + c.logger.Info("%v: client://%v@%v/%v?min=%v&mode=%v&read=%v&rate=%v&slot=%v&proxy=%v¬cp=%v&noudp=%v", prefix, c.tunnelKey, c.tunnelTCPAddr, c.getTargetAddrsString(), - c.minPoolCapacity, c.runMode, c.readTimeout, c.rateLimit/125000, c.slotLimit, c.proxyProtocol, c.disableUDP) + c.minPoolCapacity, c.runMode, c.readTimeout, c.rateLimit/125000, c.slotLimit, c.proxyProtocol, c.disableTCP, c.disableUDP) } logInfo("Client started") @@ -157,13 +156,15 @@ func (c *Client) commonStart() error { }) go c.tunnelPool.ClientManager() + // 判断数据流向 if c.dataFlow == "+" { - // 初始化目标监听器 if err := c.initTargetListener(); err != nil { return fmt.Errorf("commonStart: initTargetListener failed: %w", err) } go c.commonLoop() } + + // 启动共用控制 if err := c.commonControl(); err != nil { return fmt.Errorf("commonStart: commonControl failed: %w", err) } diff --git a/nodepass/internal/common.go b/nodepass/internal/common.go index b1d4a3c860..0c80f554b9 100644 --- a/nodepass/internal/common.go +++ b/nodepass/internal/common.go @@ -5,6 +5,8 @@ import ( "bufio" "bytes" "context" + "crypto/sha256" + "crypto/tls" "encoding/base64" "encoding/hex" "fmt" @@ -29,6 +31,7 @@ type Common struct { mu sync.Mutex // 互斥锁 logger *logs.Logger // 日志记录器 tlsCode string // TLS模式代码 + tlsConfig *tls.Config // TLS配置 runMode string // 运行模式 dataFlow string // 数据流向 tunnelKey string // 隧道密钥 @@ -47,6 +50,7 @@ type Common struct { minPoolCapacity int // 最小池容量 maxPoolCapacity int // 最大池容量 proxyProtocol string // 代理协议 + disableTCP string // 禁用TCP disableUDP string // 禁用UDP rateLimit int // 速率限制 rateLimiter *conn.RateLimiter // 全局限速器 @@ -56,8 +60,6 @@ type Common struct { udpBufferPool *sync.Pool // UDP缓冲区池 signalChan chan string // 信号通道 checkPoint time.Time // 检查点时间 - lastClean time.Time // 上次清理时间 - cleanURL *url.URL // 清理信号 flushURL *url.URL // 重置信号 pingURL *url.URL // PING信号 pongURL *url.URL // PONG信号 @@ -99,6 +101,7 @@ const ( defaultRateLimit = 0 // 默认速率限制 defaultSlotLimit = 65536 // 默认槽位限制 defaultProxyProtocol = "0" // 默认代理协议 + defaultTCPStrategy = "0" // 默认TCP策略 defaultUDPStrategy = "0" // 默认UDP策略 ) @@ -184,6 +187,22 @@ func getEnvAsDuration(name string, defaultValue time.Duration) time.Duration { return defaultValue } +// formatCertFingerprint 格式化证书指纹为标准格式 +func (c *Common) formatCertFingerprint(certRaw []byte) string { + hash := sha256.Sum256(certRaw) + hashHex := hex.EncodeToString(hash[:]) + + var formatted strings.Builder + for i := 0; i < len(hashHex); i += 2 { + if i > 0 { + formatted.WriteByte(':') + } + formatted.WriteString(strings.ToUpper(hashHex[i : i+2])) + } + + return "sha256:" + formatted.String() +} + // xor 对数据进行异或处理 func (c *Common) xor(data []byte) []byte { for i := range data { @@ -404,6 +423,15 @@ func (c *Common) getProxyProtocol(parsedURL *url.URL) { } } +// getTCPStrategy 获取TCP策略 +func (c *Common) getTCPStrategy(parsedURL *url.URL) { + if tcpStrategy := parsedURL.Query().Get("notcp"); tcpStrategy != "" { + c.disableTCP = tcpStrategy + } else { + c.disableTCP = defaultTCPStrategy + } +} + // getUDPStrategy 获取UDP策略 func (c *Common) getUDPStrategy(parsedURL *url.URL) { if udpStrategy := parsedURL.Query().Get("noudp"); udpStrategy != "" { @@ -426,6 +454,7 @@ func (c *Common) initConfig(parsedURL *url.URL) error { c.getRateLimit(parsedURL) c.getSlotLimit(parsedURL) c.getProxyProtocol(parsedURL) + c.getTCPStrategy(parsedURL) c.getUDPStrategy(parsedURL) return nil @@ -490,7 +519,7 @@ func (c *Common) initTunnelListener() error { } // 初始化隧道TCP监听器 - if c.tunnelTCPAddr != nil { + if c.tunnelTCPAddr != nil && c.disableTCP != "1" { tunnelListener, err := net.ListenTCP("tcp", c.tunnelTCPAddr) if err != nil { return fmt.Errorf("initTunnelListener: listenTCP failed: %w", err) @@ -517,7 +546,7 @@ func (c *Common) initTargetListener() error { } // 初始化目标TCP监听器 - if len(c.targetTCPAddrs) > 0 { + if len(c.targetTCPAddrs) > 0 && c.disableTCP != "1" { targetListener, err := net.ListenTCP("tcp", c.targetTCPAddrs[0]) if err != nil { return fmt.Errorf("initTargetListener: listenTCP failed: %w", err) @@ -686,27 +715,20 @@ func (c *Common) healthCheck() error { ticker := time.NewTicker(reportInterval) defer ticker.Stop() + go func() { + select { + case <-c.ctx.Done(): + case <-ticker.C: + c.incomingVerify() + } + }() + for c.ctx.Err() == nil { // 尝试获取锁 if !c.mu.TryLock() { continue } - // 连接池定期清理 - if time.Since(c.lastClean) >= ReloadInterval { - // 发送清理信号到对端 - if c.ctx.Err() == nil && c.tunnelTCPConn != nil { - _, err := c.tunnelTCPConn.Write(c.encode([]byte(c.cleanURL.String()))) - if err != nil { - c.mu.Unlock() - return fmt.Errorf("healthCheck: write clean signal failed: %w", err) - } - } - c.tunnelPool.Clean() - c.lastClean = time.Now() - c.logger.Debug("Tunnel pool cleaned: %v active connections", c.tunnelPool.Active()) - } - // 连接池健康度检查 if c.tunnelPool.ErrorCount() > c.tunnelPool.Active()/2 { // 发送刷新信号到对端 @@ -750,6 +772,57 @@ func (c *Common) healthCheck() error { return fmt.Errorf("healthCheck: context error: %w", c.ctx.Err()) } +// incomingVerify 入口连接验证 +func (c *Common) incomingVerify() { + for c.ctx.Err() == nil { + if c.tunnelPool.Ready() { + break + } + select { + case <-c.ctx.Done(): + continue + case <-time.After(50 * time.Millisecond): + } + } + + if c.tlsConfig == nil || len(c.tlsConfig.Certificates) == 0 { + return + } + + cert := c.tlsConfig.Certificates[0] + if len(cert.Certificate) == 0 { + return + } + + // 打印证书指纹 + c.logger.Info("TLS cert verified: %v", c.formatCertFingerprint(cert.Certificate[0])) + + id, testConn, err := c.tunnelPool.IncomingGet(poolGetTimeout) + if err != nil { + return + } + defer testConn.Close() + + // 构建并发送验证信号 + verifyURL := &url.URL{ + Scheme: "np", + Host: c.tunnelTCPConn.RemoteAddr().String(), + Path: url.PathEscape(id), + Fragment: "v", // TLS验证 + } + + if c.ctx.Err() == nil && c.tunnelTCPConn != nil { + c.mu.Lock() + _, err = c.tunnelTCPConn.Write(c.encode([]byte(verifyURL.String()))) + c.mu.Unlock() + if err != nil { + return + } + } + + c.logger.Debug("TLS verify signal: cid %v -> %v", id, c.tunnelTCPConn.RemoteAddr()) +} + // commonLoop 共用处理循环 func (c *Common) commonLoop() { for c.ctx.Err() == nil { @@ -1029,26 +1102,18 @@ func (c *Common) commonOnce() error { // 处理信号 switch signalURL.Fragment { + case "v": // 验证 + if c.tlsCode == "1" || c.tlsCode == "2" { + go c.outgoingVerify(signalURL) + } case "1": // TCP - if len(c.targetTCPAddrs) > 0 { + if c.disableTCP != "1" { go c.commonTCPOnce(signalURL) } case "2": // UDP if c.disableUDP != "1" { go c.commonUDPOnce(signalURL) } - case "c": // 连接池清理 - go func() { - c.tunnelPool.Clean() - - select { - case <-c.ctx.Done(): - return - case <-time.After(reportInterval): - } - - c.logger.Debug("Tunnel pool cleaned: %v active connections", c.tunnelPool.Active()) - }() case "f": // 连接池刷新 go func() { c.tunnelPool.Flush() @@ -1087,6 +1152,54 @@ func (c *Common) commonOnce() error { return fmt.Errorf("commonOnce: context error: %w", c.ctx.Err()) } +// outgoingVerify 出口连接验证 +func (c *Common) outgoingVerify(signalURL *url.URL) { + for c.ctx.Err() == nil { + if c.tunnelPool.Ready() { + break + } + select { + case <-c.ctx.Done(): + continue + case <-time.After(50 * time.Millisecond): + } + } + + id := strings.TrimPrefix(signalURL.Path, "/") + if unescapedID, err := url.PathUnescape(id); err != nil { + c.logger.Error("outgoingVerify: unescape id failed: %v", err) + return + } else { + id = unescapedID + } + c.logger.Debug("TLS verify signal: cid %v <- %v", id, c.tunnelTCPConn.RemoteAddr()) + + testConn, err := c.tunnelPool.OutgoingGet(id, poolGetTimeout) + if err != nil { + c.logger.Error("outgoingVerify: request timeout: %v", err) + c.tunnelPool.AddError() + return + } + defer testConn.Close() + + if testConn != nil { + tlsConn, ok := testConn.(*tls.Conn) + if !ok { + c.logger.Error("outgoingVerify: connection is not TLS") + return + } + + state := tlsConn.ConnectionState() + if len(state.PeerCertificates) == 0 { + c.logger.Error("outgoingVerify: no peer certificates found") + return + } + + // 打印证书指纹 + c.logger.Info("TLS cert verified: %v", c.formatCertFingerprint(state.PeerCertificates[0].Raw)) + } +} + // commonTCPOnce 共用处理单个TCP请求 func (c *Common) commonTCPOnce(signalURL *url.URL) { id := strings.TrimPrefix(signalURL.Path, "/") diff --git a/nodepass/internal/master.go b/nodepass/internal/master.go index 75ee54abc6..a8dbf42dd3 100644 --- a/nodepass/internal/master.go +++ b/nodepass/internal/master.go @@ -31,14 +31,15 @@ import ( // 常量定义 const ( - openAPIVersion = "v1" // OpenAPI版本 - stateFilePath = "gob" // 实例状态持久化文件路径 - stateFileName = "nodepass.gob" // 实例状态持久化文件名 - sseRetryTime = 3000 // 重试间隔时间(毫秒) - apiKeyID = "********" // API Key的特殊ID - tcpingSemLimit = 10 // TCPing最大并发数 - baseDuration = 100 * time.Millisecond // 基准持续时间 - maxValueLen = 256 // 字符长度限制 + openAPIVersion = "v1" // OpenAPI版本 + stateFilePath = "gob" // 实例状态持久化文件路径 + stateFileName = "nodepass.gob" // 实例状态持久化文件名 + sseRetryTime = 3000 // 重试间隔时间(毫秒) + apiKeyID = "********" // API Key的特殊ID + tcpingSemLimit = 10 // TCPing最大并发数 + baseDuration = 100 * time.Millisecond // 基准持续时间 + gracefulTimeout = 5 * time.Second // 优雅关闭超时 + maxValueLen = 256 // 字符长度限制 ) // Swagger UI HTML模板 @@ -1662,30 +1663,39 @@ func (m *Master) stopInstance(instance *Instance) { return } - // 发送终止信号 - if instance.cmd.Process != nil { - if runtime.GOOS == "windows" { - instance.cmd.Process.Signal(os.Interrupt) - } else { - instance.cmd.Process.Signal(syscall.SIGTERM) - } - time.Sleep(baseDuration) + // 关闭停止通道 + select { + case <-instance.stopped: + default: + close(instance.stopped) } - // 关闭停止通道 - close(instance.stopped) - - // 取消执行或强制终止 + // 发送终止信号并取消上下文 + process := instance.cmd.Process + if runtime.GOOS == "windows" { + process.Signal(os.Interrupt) + } else { + process.Signal(syscall.SIGTERM) + } if instance.cancelFunc != nil { instance.cancelFunc() - } else { - err := instance.cmd.Process.Kill() - if err != nil { - m.logger.Error("stopInstance: instance error: %v [%v]", err, instance.ID) - } } - m.logger.Info("Instance stopped [%v]", instance.ID) + // 等待优雅退出或超时强制终止 + done := make(chan struct{}) + go func() { + process.Wait() + close(done) + }() + + select { + case <-done: + m.logger.Info("Instance stopped [%v]", instance.ID) + case <-time.After(gracefulTimeout): + process.Kill() + <-done + m.logger.Warn("Instance force killed [%v]", instance.ID) + } // 重置实例状态 instance.Status = "stopped" @@ -1775,7 +1785,7 @@ func (m *Master) generateConfigURL(instance *Instance) string { // 根据实例类型设置默认参数 switch instance.Type { case "client": - // client参数: min, mode, read, rate, slot, proxy, noudp + // client参数: min, mode, read, rate, slot, proxy, notcp, noudp if query.Get("min") == "" { query.Set("min", strconv.Itoa(defaultMinPool)) } @@ -1794,11 +1804,14 @@ func (m *Master) generateConfigURL(instance *Instance) string { if query.Get("proxy") == "" { query.Set("proxy", defaultProxyProtocol) } + if query.Get("notcp") == "" { + query.Set("notcp", defaultTCPStrategy) + } if query.Get("noudp") == "" { query.Set("noudp", defaultUDPStrategy) } case "server": - // server参数: max, mode, read, rate, slot, proxy, noudp + // server参数: max, mode, read, rate, slot, proxy, notcp, noudp if query.Get("max") == "" { query.Set("max", strconv.Itoa(defaultMaxPool)) } @@ -1817,6 +1830,9 @@ func (m *Master) generateConfigURL(instance *Instance) string { if query.Get("proxy") == "" { query.Set("proxy", defaultProxyProtocol) } + if query.Get("notcp") == "" { + query.Set("notcp", defaultTCPStrategy) + } if query.Get("noudp") == "" { query.Set("noudp", defaultUDPStrategy) } diff --git a/nodepass/internal/server.go b/nodepass/internal/server.go index 5e36250c3b..5c98492aad 100644 --- a/nodepass/internal/server.go +++ b/nodepass/internal/server.go @@ -23,9 +23,8 @@ import ( // Server 实现服务端模式功能 type Server struct { - Common // 继承共享功能 - tlsConfig *tls.Config // TLS配置 - clientIP string // 客户端IP + Common // 继承共享功能 + clientIP string // 客户端IP } // NewServer 创建新的服务端实例 @@ -33,6 +32,7 @@ func NewServer(parsedURL *url.URL, tlsCode string, tlsConfig *tls.Config, logger server := &Server{ Common: Common{ tlsCode: tlsCode, + tlsConfig: tlsConfig, logger: logger, signalChan: make(chan string, semaphoreLimit), tcpBufferPool: &sync.Pool{ @@ -47,12 +47,10 @@ func NewServer(parsedURL *url.URL, tlsCode string, tlsConfig *tls.Config, logger return &buf }, }, - cleanURL: &url.URL{Scheme: "np", Fragment: "c"}, flushURL: &url.URL{Scheme: "np", Fragment: "f"}, pingURL: &url.URL{Scheme: "np", Fragment: "i"}, pongURL: &url.URL{Scheme: "np", Fragment: "o"}, }, - tlsConfig: tlsConfig, } if err := server.initConfig(parsedURL); err != nil { return nil, fmt.Errorf("newServer: initConfig failed: %w", err) @@ -64,9 +62,9 @@ func NewServer(parsedURL *url.URL, tlsCode string, tlsConfig *tls.Config, logger // Run 管理服务端生命周期 func (s *Server) Run() { logInfo := func(prefix string) { - s.logger.Info("%v: server://%v@%v/%v?max=%v&mode=%v&read=%v&rate=%v&slot=%v&proxy=%v&noudp=%v", + s.logger.Info("%v: server://%v@%v/%v?max=%v&mode=%v&read=%v&rate=%v&slot=%v&proxy=%v¬cp=%v&noudp=%v", prefix, s.tunnelKey, s.tunnelTCPAddr, s.getTargetAddrsString(), - s.maxPoolCapacity, s.runMode, s.readTimeout, s.rateLimit/125000, s.slotLimit, s.proxyProtocol, s.disableUDP) + s.maxPoolCapacity, s.runMode, s.readTimeout, s.rateLimit/125000, s.slotLimit, s.proxyProtocol, s.disableTCP, s.disableUDP) } logInfo("Server started") @@ -152,9 +150,12 @@ func (s *Server) start() error { reportInterval) go s.tunnelPool.ServerManager() + // 判断数据流向 if s.dataFlow == "-" { go s.commonLoop() } + + // 启动共用控制 if err := s.commonControl(); err != nil { return fmt.Errorf("start: commonControl failed: %w", err) } diff --git a/openwrt-packages/luci-lib-taskd/Makefile b/openwrt-packages/luci-lib-taskd/Makefile index 2be891297a..5217c0eab7 100644 --- a/openwrt-packages/luci-lib-taskd/Makefile +++ b/openwrt-packages/luci-lib-taskd/Makefile @@ -11,7 +11,7 @@ LUCI_DEPENDS:=+luci-lib-xterm +taskd LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3) LUCI_PKGARCH:=all -PKG_VERSION:=1.0.24 +PKG_VERSION:=1.0.25 PKG_RELEASE:= PKG_MAINTAINER:=jjm2473 diff --git a/openwrt-packages/luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.js b/openwrt-packages/luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.js index 9a5b7957d7..5115d3e9cd 100644 --- a/openwrt-packages/luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.js +++ b/openwrt-packages/luci-lib-taskd/htdocs/luci-static/resources/tasks/tasks.js @@ -23,7 +23,7 @@ oReq.onload = function (oEvent) { if (oReq.status == 403) { alert($gettext("Lost login status")); - location.href = location.href; + location.href = location.href.replace(/#.*$/,''); } else if (oReq.status >= 400) { reject(oEvent); } else { @@ -98,7 +98,7 @@ running=false; showing=false; del_task(task_id).then(()=>{ - location.href = location.href; + location.href = location.href.replace(/#.*$/,''); }); } return false; diff --git a/openwrt-passwall/luci-app-passwall/luasrc/controller/passwall.lua b/openwrt-passwall/luci-app-passwall/luasrc/controller/passwall.lua index 831941c1bc..91b8c1a76b 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/controller/passwall.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/controller/passwall.lua @@ -77,10 +77,12 @@ function index() entry({"admin", "services", appname, "connect_status"}, call("connect_status")).leaf = true entry({"admin", "services", appname, "ping_node"}, call("ping_node")).leaf = true entry({"admin", "services", appname, "urltest_node"}, call("urltest_node")).leaf = true + entry({"admin", "services", appname, "add_node"}, call("add_node")).leaf = true entry({"admin", "services", appname, "set_node"}, call("set_node")).leaf = true entry({"admin", "services", appname, "copy_node"}, call("copy_node")).leaf = true entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true + entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true @@ -397,6 +399,21 @@ function urltest_node() http_write_json(e) end +function add_node() + local redirect = http.formvalue("redirect") + + local uuid = api.gen_short_uuid() + uci:section(appname, "nodes", uuid) + + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_config", uuid)) + else + api.uci_save(uci, appname, true, true) + http_write_json({result = uuid}) + end +end + function set_node() local protocol = http.formvalue("protocol") local section = http.formvalue("section") @@ -420,7 +437,7 @@ function copy_node() end) end end - uci:delete(appname, uuid, "add_from") + uci:delete(appname, uuid, "group") uci:set(appname, uuid, "add_mode", 1) api.uci_save(uci, appname) http.redirect(api.url("node_config", uuid)) @@ -458,6 +475,7 @@ end function delete_select_nodes() local ids = http.formvalue("ids") + local redirect = http.formvalue("redirect") string.gsub(ids, '[^' .. "," .. ']+', function(w) if (uci:get(appname, "@global[0]", "tcp_node") or "") == w then uci:delete(appname, '@global[0]', "tcp_node") @@ -532,10 +550,10 @@ function delete_select_nodes() end end) if (uci:get(appname, w, "add_mode") or "0") == "2" then - local add_from = uci:get(appname, w, "add_from") or "" - if add_from ~= "" then + local group = uci:get(appname, w, "group") or "" + if group ~= "" then uci:foreach(appname, "subscribe_list", function(t) - if t["remark"] == add_from then + if t["remark"] == group then uci:delete(appname, t[".name"], "md5") end end) @@ -543,7 +561,40 @@ function delete_select_nodes() end uci:delete(appname, w) end) - api.uci_save(uci, appname, true, true) + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_list")) + else + api.uci_save(uci, appname, true, true) + end +end + + +function get_node() + local id = http.formvalue("id") + local result = {} + local show_node_info = api.uci_get_type("@global_other[0]", "show_node_info", "0") + + function add_is_ipv6_key(o) + if o and o.address and show_node_info == "1" then + local f = api.get_ipv6_full(o.address) + if f ~= "" then + o.ipv6 = true + o.full_address = f + end + end + end + + if id then + result = uci:get_all(appname, id) + add_is_ipv6_key(result) + else + uci:foreach(appname, "nodes", function(t) + add_is_ipv6_key(t) + result[#result + 1] = t + end) + end + http_write_json(result) end function update_rules() diff --git a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua index 31c6d12919..03d6fab6ce 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua @@ -22,6 +22,19 @@ o = s:option(Value, "remarks", translate("Node Remarks")) o.default = translate("Remarks") o.rmempty = false +o = s:option(Value, "group", translate("Group Name")) +local groups = {} +m.uci:foreach(appname, "nodes", function(s) + if s[".name"] ~= arg[1] then + if s.group then + groups[s.group] = true + end + end +end) +for k, v in pairs(groups) do + o:value(k) +end + o = s:option(ListValue, "type", translate("Type")) if api.is_finded("ipt2socks") then diff --git a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua index f5f29e367a..58348cbaab 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua @@ -21,221 +21,6 @@ o.default = "0" -- [[ Add the node via the link ]]-- s:append(Template(appname .. "/node_list/link_add_node")) -local auto_detection_time = m:get("@global_other[0]", "auto_detection_time") or "0" -local show_node_info = m:get("@global_other[0]", "show_node_info") or "0" - --- [[ Node List ]]-- -s = m:section(TypedSection, "nodes") -s.anonymous = true -s.addremove = true -s.template = "cbi/tblsection" -s.extedit = api.url("node_config", "%s") -function s.create(e, t) - local uuid = api.gen_short_uuid() - t = uuid - TypedSection.create(e, t) - luci.http.redirect(e.extedit:format(t)) -end - -function s.remove(e, t) - m.uci:foreach(appname, "socks", function(s) - if s["node"] == t then - m:del(s[".name"]) - end - for k, v in ipairs(m:get(s[".name"], "autoswitch_backup_node") or {}) do - if v and v == t then - sys.call(string.format("uci -q del_list %s.%s.autoswitch_backup_node='%s'", appname, s[".name"], v)) - end - end - end) - m.uci:foreach(appname, "haproxy_config", function(s) - if s["lbss"] and s["lbss"] == t then - m:del(s[".name"]) - end - end) - m.uci:foreach(appname, "acl_rule", function(s) - if s["tcp_node"] and s["tcp_node"] == t then - m:set(s[".name"], "tcp_node", "default") - end - if s["udp_node"] and s["udp_node"] == t then - m:set(s[".name"], "udp_node", "default") - end - end) - m.uci:foreach(appname, "nodes", function(s) - if s["preproxy_node"] == t then - m:del(s[".name"], "preproxy_node") - m:del(s[".name"], "chain_proxy") - end - if s["to_node"] == t then - m:del(s[".name"], "to_node") - m:del(s[".name"], "chain_proxy") - end - local list_name = s["urltest_node"] and "urltest_node" or (s["balancing_node"] and "balancing_node") - if list_name then - local nodes = m.uci:get_list(appname, s[".name"], list_name) - if nodes then - local changed = false - local new_nodes = {} - for _, node in ipairs(nodes) do - if node ~= t then - table.insert(new_nodes, node) - else - changed = true - end - end - if changed then - m.uci:set_list(appname, s[".name"], list_name, new_nodes) - end - end - end - if s["fallback_node"] == t then - m:del(s[".name"], "fallback_node") - end - end) - m.uci:foreach(appname, "subscribe_list", function(s) - if s["preproxy_node"] == t then - m:del(s[".name"], "preproxy_node") - m:del(s[".name"], "chain_proxy") - end - if s["to_node"] == t then - m:del(s[".name"], "to_node") - m:del(s[".name"], "chain_proxy") - end - end) - if (m:get(t, "add_mode") or "0") == "2" then - local add_from = m:get(t, "add_from") or "" - if add_from ~= "" then - m.uci:foreach(appname, "subscribe_list", function(s) - if s["remark"] == add_from then - m:del(s[".name"], "md5") - end - end) - end - end - TypedSection.remove(e, t) - local new_node = "" - local node0 = m:get("@nodes[0]") or nil - if node0 then - new_node = node0[".name"] - end - if (m:get("@global[0]", "tcp_node") or "") == t then - m:set('@global[0]', "tcp_node", new_node) - end - if (m:get("@global[0]", "udp_node") or "") == t then - m:set('@global[0]', "udp_node", new_node) - end -end - -s.sortable = true --- 简洁模式 -o = s:option(DummyValue, "add_from", "") -o.cfgvalue = function(t, n) - local v = Value.cfgvalue(t, n) - if v and v ~= '' then - local group = m:get(n, "group") or "" - if group ~= "" then - v = v .. " " .. group - end - return v - else - return '' - end -end -o = s:option(DummyValue, "remarks", translate("Remarks")) -o.rawhtml = true -o.cfgvalue = function(t, n) - local str = "" - local is_sub = m:get(n, "is_sub") or "" - local group = m:get(n, "group") or "" - local remarks = m:get(n, "remarks") or "" - local type = m:get(n, "type") or "" - str = str .. string.format("", appname, n, type) - if type == "sing-box" or type == "Xray" then - local protocol = m:get(n, "protocol") - if protocol == "_balancing" then - protocol = translate("Balancing") - elseif protocol == "_urltest" then - protocol = "URLTest" - elseif protocol == "_shunt" then - protocol = translate("Shunt") - elseif protocol == "vmess" then - protocol = "VMess" - elseif protocol == "vless" then - protocol = "VLESS" - elseif protocol == "shadowsocks" then - protocol = "SS" - elseif protocol == "shadowsocksr" then - protocol = "SSR" - elseif protocol == "wireguard" then - protocol = "WG" - elseif protocol == "hysteria" then - protocol = "HY" - elseif protocol == "hysteria2" then - protocol = "HY2" - elseif protocol == "anytls" then - protocol = "AnyTLS" - elseif protocol == "ssh" then - protocol = "SSH" - else - protocol = protocol:gsub("^%l",string.upper) - end - if type == "sing-box" then type = "Sing-Box" end - type = type .. " " .. protocol - end - local address = m:get(n, "address") or "" - local port = m:get(n, "port") or "" - local port_s = (port ~= "") and port or m:get(n, "hysteria_hop") or m:get(n, "hysteria2_hop") or "" - str = str .. translate(type) .. ":" .. remarks - if address ~= "" and port_s ~= "" then - port_s = port_s:gsub(":", "-") - if show_node_info == "1" then - if datatypes.ip6addr(address) then - str = str .. string.format("([%s]:%s)", address, port_s) - else - str = str .. string.format("(%s:%s)", address, port_s) - end - end - end - str = str .. string.format("", appname, n, address) - str = str .. string.format("", appname, n, port) - return str -end - ----- Ping -o = s:option(DummyValue, "ping", "Ping") -o.width = "8%" -o.rawhtml = true -o.cfgvalue = function(t, n) - local result = "---" - if auto_detection_time ~= "icmp" then - result = string.format('%s', n, translate("Test")) - else - result = string.format('---', n) - end - return result -end - ----- TCP Ping -o = s:option(DummyValue, "tcping", "TCPing") -o.width = "8%" -o.rawhtml = true -o.cfgvalue = function(t, n) - local result = "---" - if auto_detection_time ~= "tcping" then - result = string.format('%s', n, translate("Test")) - else - result = string.format('---', n) - end - return result -end - -o = s:option(DummyValue, "_url_test", translate("URL Test")) -o.width = "8%" -o.rawhtml = true -o.cfgvalue = function(t, n) - return string.format('%s', n, translate("Test")) -end - m:append(Template(appname .. "/node_list/node_list")) return m diff --git a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua index a604594b36..e7157ec38d 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua @@ -202,7 +202,7 @@ o.cfgvalue = function(t, n) str = str ~= "" and "
" .. str or "" local num = 0 m.uci:foreach(appname, "nodes", function(s) - if s["add_from"] ~= "" and s["add_from"] == remark then + if s["group"] ~= "" and s["group"] == remark then num = num + 1 end end) diff --git a/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm b/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm index 5acf53fb4b..a91103c6b5 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm +++ b/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm @@ -79,6 +79,10 @@ local api = require "luci.passwall.api" } } + function add_new_node() { + window.location.href = '<%=api.url("add_node")%>?redirect=1'; + } + //]]> @@ -99,7 +103,7 @@ local api = require "luci.passwall.api"
- + @@ -107,7 +111,6 @@ local api = require "luci.passwall.api" -
diff --git a/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm index 6ab4cd67ab..268d033742 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm +++ b/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm @@ -44,12 +44,48 @@ table td, .table .td { } + +<% if api.is_js_luci() then -%> + +<%- end %> + - var edit_btn = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-button cbi-button-edit"); - for (var i = 0; i < edit_btn.length; i++) { - try { - var onclick_str = edit_btn[i].getAttribute("onclick"); - var id = onclick_str.substring(onclick_str.lastIndexOf('/') + 1, onclick_str.length - 1); - var td = edit_btn[i].parentNode; - var new_div = ""; - //添加"勾选"框 - new_div += '  '; - //添加"置顶"按钮 - new_div += '  '; - //添加"应用"按钮 - new_div += '  '; - //添加"复制"按钮 - new_div += '  '; - td.innerHTML = new_div + td.innerHTML; + - var obj = {}; - obj.id = id; - obj.type = document.getElementById("cbid.passwall." + id + ".type").value; - var address_dom = document.getElementById("cbid.passwall." + id + ".address"); - var port_dom = document.getElementById("cbid.passwall." + id + ".port"); - if (address_dom && port_dom) { - obj.address = address_dom.value; - obj.port = port_dom.value; + + +
+
+ + @@ -99,7 +103,7 @@ local api = require "luci.passwall2.api"
- + @@ -107,7 +111,6 @@ local api = require "luci.passwall2.api" -
diff --git a/openwrt-passwall2/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm b/openwrt-passwall2/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm index c694d4f655..e9965092e7 100644 --- a/openwrt-passwall2/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm +++ b/openwrt-passwall2/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm @@ -61,11 +61,46 @@ table td, .table .td { } +<% if api.is_js_luci() then -%> + +<%- end %> + + + + + + + +
+
+ + diff --git a/openwrt-passwall2/luci-app-passwall2/po/zh-cn/passwall2.po b/openwrt-passwall2/luci-app-passwall2/po/zh-cn/passwall2.po index 4d2711f592..e547c26543 100644 --- a/openwrt-passwall2/luci-app-passwall2/po/zh-cn/passwall2.po +++ b/openwrt-passwall2/luci-app-passwall2/po/zh-cn/passwall2.po @@ -1836,3 +1836,9 @@ msgstr "如留空,则使用随机版本。" msgid "The configured type also applies to the core specified when manually importing nodes." msgstr "配置的类型同样适用于手动导入节点时所指定的核心程序。" + +msgid "Group Name" +msgstr "分组名" + +msgid "Using..." +msgstr "使用中。" diff --git a/openwrt-passwall2/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 b/openwrt-passwall2/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 index cb52b9cc32..676dad41b5 100755 --- a/openwrt-passwall2/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 +++ b/openwrt-passwall2/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 @@ -35,13 +35,13 @@ EOF chmod +x /usr/share/passwall2/*.sh -[ -e "/etc/config/passwall2_show" ] && rm -rf /etc/config/passwall2_show - [ "$(uci -q get passwall2.@global_xray[0].sniffing)" == "1" ] && [ "$(uci -q get passwall2.@global_xray[0].route_only)" != "1" ] && uci -q set passwall2.@global_xray[0].sniffing_override_dest=1 uci -q delete passwall2.@global_xray[0].sniffing uci -q delete passwall2.@global_xray[0].route_only uci -q commit passwall2 +sed -i "s#add_from#group#g" /etc/config/passwall2 2>/dev/null + rm -f /tmp/luci-indexcache rm -rf /tmp/luci-modulecache/ killall -HUP rpcd 2>/dev/null diff --git a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/app.sh b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/app.sh index 474560f7f6..feb0fbed23 100755 --- a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/app.sh +++ b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -1343,7 +1343,7 @@ stop() { # 结束 SS 插件进程 # kill_all xray-plugin v2ray-plugin obfs-local shadow-tls local pid_file pid - find "$TMP_PATH" -type f -name '*_plugin.pid' | while read -r pid_file; do + find "$TMP_PATH" -type f -name '*_plugin.pid' 2>/dev/null | while read -r pid_file; do read -r pid < "$pid_file" if [ -n "$pid" ]; then kill -9 "$pid" >/dev/null 2>&1 diff --git a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/iptables.sh index 44cc493460..6e53426535 100755 --- a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/iptables.sh +++ b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/iptables.sh @@ -358,7 +358,7 @@ load_acl() { ipset -! create $ipset_white6 nethash family inet6 maxelem 1048576 #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${node} shunt_list4 shunt_list6 ${write_ipset_direct} ${ipset_white} ${ipset_white6} + gen_shunt_list "${node}" shunt_list4 shunt_list6 ${write_ipset_direct} ${ipset_white} ${ipset_white6} fi } @@ -671,7 +671,7 @@ filter_direct_node_list() { } add_firewall_rule() { - echolog "开始加载防火墙规则..." + echolog "开始加载 iptables 防火墙规则..." ipset -! create $IPSET_LOCAL nethash maxelem 1048576 ipset -! create $IPSET_LAN nethash maxelem 1048576 ipset -! create $IPSET_VPS nethash maxelem 1048576 @@ -735,7 +735,7 @@ add_firewall_rule() { ipset -! create $ipset_global_white6 nethash family inet6 maxelem 1048576 timeout 259200 #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${NODE} SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${ipset_global_white} ${ipset_global_white6} + gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${ipset_global_white} ${ipset_global_white6} # 过滤所有节点IP filter_vpsip > /dev/null 2>&1 & @@ -772,31 +772,28 @@ add_firewall_rule() { else $ipt_n -I PREROUTING -j PSW2_DNS fi - - $ipt_m -N PSW2_DIVERT - $ipt_m -A PSW2_DIVERT -j MARK --set-mark 1 - $ipt_m -A PSW2_DIVERT -j ACCEPT $ipt_m -N PSW2_RULE $ipt_m -A PSW2_RULE -j CONNMARK --restore-mark $ipt_m -A PSW2_RULE -m mark --mark 0x1 -j RETURN - $ipt_m -A PSW2_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 - $ipt_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 + $ipt_m -A PSW2_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 + $ipt_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 $ipt_m -A PSW2_RULE -j CONNMARK --save-mark $ipt_m -N PSW2 $ipt_m -A PSW2 $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW2 $(dst $IPSET_VPS) -j RETURN + $ipt_m -A PSW2 -m conntrack --ctdir REPLY -j RETURN [ ! -z "${WAN_IP}" ] && $ipt_m -A PSW2 $(comment "WAN_IP_RETURN") -d "${WAN_IP}" -j RETURN unset WAN_IP insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW2" - insert_rule_before "$ipt_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT" $ipt_m -N PSW2_OUTPUT $ipt_m -A PSW2_OUTPUT $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW2_OUTPUT $(dst $IPSET_VPS) -j RETURN + $ipt_m -A PSW2_OUTPUT -m conntrack --ctdir REPLY -j RETURN [ -n "$AUTO_DNS" ] && { for auto_dns in $(echo $AUTO_DNS | tr ',' ' '); do local dns_address=$(echo $auto_dns | awk -F '#' '{print $1}') @@ -829,33 +826,30 @@ add_firewall_rule() { else $ip6t_n -I PREROUTING -j PSW2_DNS fi - - $ip6t_m -N PSW2_DIVERT - $ip6t_m -A PSW2_DIVERT -j MARK --set-mark 1 - $ip6t_m -A PSW2_DIVERT -j ACCEPT $ip6t_m -N PSW2_RULE $ip6t_m -A PSW2_RULE -j CONNMARK --restore-mark $ip6t_m -A PSW2_RULE -m mark --mark 0x1 -j RETURN - $ip6t_m -A PSW2_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 - $ip6t_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 + $ip6t_m -A PSW2_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 + $ip6t_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 $ip6t_m -A PSW2_RULE -j CONNMARK --save-mark $ip6t_m -N PSW2 $ip6t_m -A PSW2 $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW2 $(dst $IPSET_VPS6) -j RETURN + $ip6t_m -A PSW2 -m conntrack --ctdir REPLY -j RETURN WAN6_IP=$(get_wan6_ip) [ ! -z "${WAN6_IP}" ] && $ip6t_m -A PSW2 $(comment "WAN6_IP_RETURN") -d ${WAN6_IP} -j RETURN unset WAN6_IP insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW2" - insert_rule_before "$ip6t_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT" $ip6t_m -N PSW2_OUTPUT $ip6t_m -A PSW2_OUTPUT -m mark --mark 0xff -j RETURN $ip6t_m -A PSW2_OUTPUT $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW2_OUTPUT $(dst $IPSET_VPS6) -j RETURN + $ip6t_m -A PSW2_OUTPUT -m conntrack --ctdir REPLY -j RETURN ip -6 rule add fwmark 1 table 100 ip -6 route add local ::/0 dev lo table 100 @@ -1000,7 +994,7 @@ del_firewall_rule() { $ipt -D $chain $index 2>/dev/null done done - for chain in "PSW2" "PSW2_OUTPUT" "PSW2_DIVERT" "PSW2_DNS" "PSW2_RULE"; do + for chain in "PSW2" "PSW2_OUTPUT" "PSW2_DNS" "PSW2_RULE"; do $ipt -F $chain 2>/dev/null $ipt -X $chain 2>/dev/null done @@ -1034,7 +1028,7 @@ gen_include() { [ -z "${_ipt}" ] && return echo "*$2" - ${_ipt}-save -t $2 | grep "PSW2" | grep -v "\-j PSW2$" | grep -v "socket \-j PSW2_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + ${_ipt}-save -t $2 | grep "PSW2" | grep -v "\-j PSW2$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" echo 'COMMIT' } local __ipt="" @@ -1050,7 +1044,6 @@ gen_include() { [ -z "${is_tproxy}" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW2") \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW2") - \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT") WAN_IP=\$(${MY_PATH} get_wan_ip) @@ -1078,7 +1071,6 @@ gen_include() { [ "$accept_icmpv6" = "1" ] && $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW2 \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW2") - \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT") PR_INDEX=\$(${MY_PATH} RULE_LAST_INDEX "$ip6t_m" PSW2 WAN6_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/nftables.sh index 4d6b946d1b..2785e41439 100755 --- a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/nftables.sh +++ b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/nftables.sh @@ -382,7 +382,7 @@ load_acl() { gen_nftset $nftset_white6 ipv6_addr 3d 3d #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${node} shunt_list4 shunt_list6 ${write_ipset_direct} ${nftset_white} ${nftset_white6} + gen_shunt_list "${node}" shunt_list4 shunt_list6 ${write_ipset_direct} ${nftset_white} ${nftset_white6} fi } @@ -701,7 +701,7 @@ filter_direct_node_list() { } add_firewall_rule() { - echolog "开始加载防火墙规则..." + echolog "开始加载 nftables 防火墙规则..." gen_nft_tables gen_nftset $NFTSET_LOCAL ipv4_addr 0 "-1" gen_nftset $NFTSET_LAN ipv4_addr 0 "-1" $(gen_lanlist) @@ -749,7 +749,7 @@ add_firewall_rule() { gen_nftset $nftset_global_white6 ipv6_addr 0 0 #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${NODE} SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${nftset_global_white} ${nftset_global_white6} + gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${nftset_global_white} ${nftset_global_white6} # 过滤所有节点IP filter_vpsip > /dev/null 2>&1 & @@ -771,10 +771,6 @@ add_firewall_rule() { nft_output_chain="PSW2_OUTPUT_MANGLE" fi - nft "add chain $NFTABLE_NAME PSW2_DIVERT" - nft "flush chain $NFTABLE_NAME PSW2_DIVERT" - nft "add rule $NFTABLE_NAME PSW2_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept" - nft "add chain $NFTABLE_NAME PSW2_DNS" nft "flush chain $NFTABLE_NAME PSW2_DNS" if [ $(config_t_get global dns_redirect "1") = "0" ]; then @@ -790,8 +786,8 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW2_RULE" nft "add rule $NFTABLE_NAME PSW2_RULE meta mark set ct mark counter" nft "add rule $NFTABLE_NAME PSW2_RULE meta mark 1 counter return" - nft "add rule $NFTABLE_NAME PSW2_RULE tcp flags &(fin|syn|rst|ack) == syn meta mark set mark and 0x0 xor 0x1 counter" - nft "add rule $NFTABLE_NAME PSW2_RULE meta l4proto udp ct state new meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW2_RULE tcp flags syn meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW2_RULE meta l4proto udp ct state new,related meta mark set mark and 0x0 xor 0x1 counter" nft "add rule $NFTABLE_NAME PSW2_RULE ct mark set mark counter" #ipv4 tproxy mode and udp @@ -799,11 +795,13 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW2_MANGLE" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ct direction reply counter return" [ -n "$AUTO_DNS" ] && { for auto_dns in $(echo $AUTO_DNS | tr ',' ' '); do local dns_address=$(echo $auto_dns | awk -F '#' '{print $1}') @@ -817,7 +815,6 @@ add_firewall_rule() { # jump chains nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol udp counter jump PSW2_MANGLE" [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol tcp counter jump PSW2_MANGLE" - insert_rule_before "$NFTABLE_NAME" "mangle_prerouting" "PSW2_MANGLE" "counter jump PSW2_DIVERT" #ipv4 tcp redirect mode [ -z "${is_tproxy}" ] && { @@ -865,11 +862,13 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW2_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ct direction reply counter return" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta mark 0xff counter return" # jump chains @@ -1067,7 +1066,7 @@ gen_include() { local __nft=" " __nft=$(cat <<- EOF - [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW2_DIVERT)" ] && nft -f ${nft_chain_file} + [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW2)" ] && nft -f ${nft_chain_file} [ -z "${is_tproxy}" ] && { PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "$NFTABLE_NAME" PSW2_NAT WAN_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index c2191e189f..384e65db05 100755 --- a/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -444,12 +444,12 @@ local function get_subscribe_info(cfgid, value) end -- 处理数据 -local function processData(szType, content, add_mode, add_from) - --log(content, add_mode, add_from) +local function processData(szType, content, add_mode, group) + --log(content, add_mode, group) local result = { timeout = 60, add_mode = add_mode, --0为手动配置,1为导入,2为订阅 - add_from = add_from + group = group } --ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0) if szType == 'ssr' then @@ -1544,14 +1544,14 @@ local function curl(url, file, ua, mode) return tonumber(result) end -local function truncate_nodes(add_from) +local function truncate_nodes(group) for _, config in pairs(CONFIG) do if config.currentNodes and #config.currentNodes > 0 then local newNodes = {} local removeNodesSet = {} for k, v in pairs(config.currentNodes) do if v.currentNode and v.currentNode.add_mode == "2" then - if (not add_from) or (add_from and add_from == v.currentNode.add_from) then + if (not group) or (group and group == v.currentNode.group) then removeNodesSet[v.currentNode[".name"]] = true end end @@ -1566,7 +1566,7 @@ local function truncate_nodes(add_from) end else if config.currentNode and config.currentNode.add_mode == "2" then - if (not add_from) or (add_from and add_from == config.currentNode.add_from) then + if (not group) or (group and group == config.currentNode.group) then if config.delete then config.delete(config) elseif config.set then @@ -1578,13 +1578,13 @@ local function truncate_nodes(add_from) end uci:foreach(appname, "nodes", function(node) if node.add_mode == "2" then - if (not add_from) or (add_from and add_from == node.add_from) then + if (not group) or (group and group == node.group) then uci:delete(appname, node['.name']) end end end) uci:foreach(appname, "subscribe_list", function(o) - if (not add_from) or add_from == o.remark then + if (not group) or group == o.remark then uci:delete(appname, o['.name'], "md5") end end) @@ -1725,7 +1725,7 @@ local function update_node(manual) if manual == 0 and next(group) then uci:foreach(appname, "nodes", function(node) -- 如果未发现新节点或手动导入的节点就不要删除了... - if node.add_mode == "2" and (node.add_from and group[node.add_from] == true) then + if node.add_mode == "2" and (node.group and group[node.group] == true) then uci:delete(appname, node['.name']) end end) @@ -1802,7 +1802,7 @@ local function update_node(manual) luci.sys.call("/etc/init.d/" .. appname .. " restart > /dev/null 2>&1 &") end -local function parse_link(raw, add_mode, add_from, cfgid) +local function parse_link(raw, add_mode, group, cfgid) if raw and #raw > 0 then local nodes, szType local node_list = {} @@ -1838,17 +1838,17 @@ local function parse_link(raw, add_mode, add_from, cfgid) xpcall(function () local result if szType == 'ssd' then - result = processData(szType, v, add_mode, add_from) + result = processData(szType, v, add_mode, group) elseif not szType then local node = api.trim(v) local dat = split(node, "://") if dat and dat[1] and dat[2] then if dat[1] == 'vmess' or dat[1] == 'ssr' then local link = api.trim(dat[2]:gsub("#.*$", "")) - result = processData(dat[1], base64Decode(link), add_mode, add_from) + result = processData(dat[1], base64Decode(link), add_mode, group) else local link = dat[2]:gsub("&", "&"):gsub("%s*#%s*", "#") -- 一些奇葩的链接用"&"当做"&","#"前后带空格 - result = processData(dat[1], link, add_mode, add_from) + result = processData(dat[1], link, add_mode, group) end end else @@ -1879,14 +1879,14 @@ local function parse_link(raw, add_mode, add_from, cfgid) end if #node_list > 0 then nodeResult[#nodeResult + 1] = { - remark = add_from, + remark = group, list = node_list } end - log('成功解析【' .. add_from .. '】节点数量: ' .. #node_list) + log('成功解析【' .. group .. '】节点数量: ' .. #node_list) else if add_mode == "2" then - log('获取到的【' .. add_from .. '】订阅内容为空,可能是订阅地址无效,或是网络问题,请诊断!') + log('获取到的【' .. group .. '】订阅内容为空,可能是订阅地址无效,或是网络问题,请诊断!') end end end diff --git a/small/luci-app-passwall/luasrc/controller/passwall.lua b/small/luci-app-passwall/luasrc/controller/passwall.lua index 831941c1bc..91b8c1a76b 100644 --- a/small/luci-app-passwall/luasrc/controller/passwall.lua +++ b/small/luci-app-passwall/luasrc/controller/passwall.lua @@ -77,10 +77,12 @@ function index() entry({"admin", "services", appname, "connect_status"}, call("connect_status")).leaf = true entry({"admin", "services", appname, "ping_node"}, call("ping_node")).leaf = true entry({"admin", "services", appname, "urltest_node"}, call("urltest_node")).leaf = true + entry({"admin", "services", appname, "add_node"}, call("add_node")).leaf = true entry({"admin", "services", appname, "set_node"}, call("set_node")).leaf = true entry({"admin", "services", appname, "copy_node"}, call("copy_node")).leaf = true entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true + entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true @@ -397,6 +399,21 @@ function urltest_node() http_write_json(e) end +function add_node() + local redirect = http.formvalue("redirect") + + local uuid = api.gen_short_uuid() + uci:section(appname, "nodes", uuid) + + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_config", uuid)) + else + api.uci_save(uci, appname, true, true) + http_write_json({result = uuid}) + end +end + function set_node() local protocol = http.formvalue("protocol") local section = http.formvalue("section") @@ -420,7 +437,7 @@ function copy_node() end) end end - uci:delete(appname, uuid, "add_from") + uci:delete(appname, uuid, "group") uci:set(appname, uuid, "add_mode", 1) api.uci_save(uci, appname) http.redirect(api.url("node_config", uuid)) @@ -458,6 +475,7 @@ end function delete_select_nodes() local ids = http.formvalue("ids") + local redirect = http.formvalue("redirect") string.gsub(ids, '[^' .. "," .. ']+', function(w) if (uci:get(appname, "@global[0]", "tcp_node") or "") == w then uci:delete(appname, '@global[0]', "tcp_node") @@ -532,10 +550,10 @@ function delete_select_nodes() end end) if (uci:get(appname, w, "add_mode") or "0") == "2" then - local add_from = uci:get(appname, w, "add_from") or "" - if add_from ~= "" then + local group = uci:get(appname, w, "group") or "" + if group ~= "" then uci:foreach(appname, "subscribe_list", function(t) - if t["remark"] == add_from then + if t["remark"] == group then uci:delete(appname, t[".name"], "md5") end end) @@ -543,7 +561,40 @@ function delete_select_nodes() end uci:delete(appname, w) end) - api.uci_save(uci, appname, true, true) + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_list")) + else + api.uci_save(uci, appname, true, true) + end +end + + +function get_node() + local id = http.formvalue("id") + local result = {} + local show_node_info = api.uci_get_type("@global_other[0]", "show_node_info", "0") + + function add_is_ipv6_key(o) + if o and o.address and show_node_info == "1" then + local f = api.get_ipv6_full(o.address) + if f ~= "" then + o.ipv6 = true + o.full_address = f + end + end + end + + if id then + result = uci:get_all(appname, id) + add_is_ipv6_key(result) + else + uci:foreach(appname, "nodes", function(t) + add_is_ipv6_key(t) + result[#result + 1] = t + end) + end + http_write_json(result) end function update_rules() diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua index 31c6d12919..03d6fab6ce 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua @@ -22,6 +22,19 @@ o = s:option(Value, "remarks", translate("Node Remarks")) o.default = translate("Remarks") o.rmempty = false +o = s:option(Value, "group", translate("Group Name")) +local groups = {} +m.uci:foreach(appname, "nodes", function(s) + if s[".name"] ~= arg[1] then + if s.group then + groups[s.group] = true + end + end +end) +for k, v in pairs(groups) do + o:value(k) +end + o = s:option(ListValue, "type", translate("Type")) if api.is_finded("ipt2socks") then diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua index f5f29e367a..58348cbaab 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua @@ -21,221 +21,6 @@ o.default = "0" -- [[ Add the node via the link ]]-- s:append(Template(appname .. "/node_list/link_add_node")) -local auto_detection_time = m:get("@global_other[0]", "auto_detection_time") or "0" -local show_node_info = m:get("@global_other[0]", "show_node_info") or "0" - --- [[ Node List ]]-- -s = m:section(TypedSection, "nodes") -s.anonymous = true -s.addremove = true -s.template = "cbi/tblsection" -s.extedit = api.url("node_config", "%s") -function s.create(e, t) - local uuid = api.gen_short_uuid() - t = uuid - TypedSection.create(e, t) - luci.http.redirect(e.extedit:format(t)) -end - -function s.remove(e, t) - m.uci:foreach(appname, "socks", function(s) - if s["node"] == t then - m:del(s[".name"]) - end - for k, v in ipairs(m:get(s[".name"], "autoswitch_backup_node") or {}) do - if v and v == t then - sys.call(string.format("uci -q del_list %s.%s.autoswitch_backup_node='%s'", appname, s[".name"], v)) - end - end - end) - m.uci:foreach(appname, "haproxy_config", function(s) - if s["lbss"] and s["lbss"] == t then - m:del(s[".name"]) - end - end) - m.uci:foreach(appname, "acl_rule", function(s) - if s["tcp_node"] and s["tcp_node"] == t then - m:set(s[".name"], "tcp_node", "default") - end - if s["udp_node"] and s["udp_node"] == t then - m:set(s[".name"], "udp_node", "default") - end - end) - m.uci:foreach(appname, "nodes", function(s) - if s["preproxy_node"] == t then - m:del(s[".name"], "preproxy_node") - m:del(s[".name"], "chain_proxy") - end - if s["to_node"] == t then - m:del(s[".name"], "to_node") - m:del(s[".name"], "chain_proxy") - end - local list_name = s["urltest_node"] and "urltest_node" or (s["balancing_node"] and "balancing_node") - if list_name then - local nodes = m.uci:get_list(appname, s[".name"], list_name) - if nodes then - local changed = false - local new_nodes = {} - for _, node in ipairs(nodes) do - if node ~= t then - table.insert(new_nodes, node) - else - changed = true - end - end - if changed then - m.uci:set_list(appname, s[".name"], list_name, new_nodes) - end - end - end - if s["fallback_node"] == t then - m:del(s[".name"], "fallback_node") - end - end) - m.uci:foreach(appname, "subscribe_list", function(s) - if s["preproxy_node"] == t then - m:del(s[".name"], "preproxy_node") - m:del(s[".name"], "chain_proxy") - end - if s["to_node"] == t then - m:del(s[".name"], "to_node") - m:del(s[".name"], "chain_proxy") - end - end) - if (m:get(t, "add_mode") or "0") == "2" then - local add_from = m:get(t, "add_from") or "" - if add_from ~= "" then - m.uci:foreach(appname, "subscribe_list", function(s) - if s["remark"] == add_from then - m:del(s[".name"], "md5") - end - end) - end - end - TypedSection.remove(e, t) - local new_node = "" - local node0 = m:get("@nodes[0]") or nil - if node0 then - new_node = node0[".name"] - end - if (m:get("@global[0]", "tcp_node") or "") == t then - m:set('@global[0]', "tcp_node", new_node) - end - if (m:get("@global[0]", "udp_node") or "") == t then - m:set('@global[0]', "udp_node", new_node) - end -end - -s.sortable = true --- 简洁模式 -o = s:option(DummyValue, "add_from", "") -o.cfgvalue = function(t, n) - local v = Value.cfgvalue(t, n) - if v and v ~= '' then - local group = m:get(n, "group") or "" - if group ~= "" then - v = v .. " " .. group - end - return v - else - return '' - end -end -o = s:option(DummyValue, "remarks", translate("Remarks")) -o.rawhtml = true -o.cfgvalue = function(t, n) - local str = "" - local is_sub = m:get(n, "is_sub") or "" - local group = m:get(n, "group") or "" - local remarks = m:get(n, "remarks") or "" - local type = m:get(n, "type") or "" - str = str .. string.format("", appname, n, type) - if type == "sing-box" or type == "Xray" then - local protocol = m:get(n, "protocol") - if protocol == "_balancing" then - protocol = translate("Balancing") - elseif protocol == "_urltest" then - protocol = "URLTest" - elseif protocol == "_shunt" then - protocol = translate("Shunt") - elseif protocol == "vmess" then - protocol = "VMess" - elseif protocol == "vless" then - protocol = "VLESS" - elseif protocol == "shadowsocks" then - protocol = "SS" - elseif protocol == "shadowsocksr" then - protocol = "SSR" - elseif protocol == "wireguard" then - protocol = "WG" - elseif protocol == "hysteria" then - protocol = "HY" - elseif protocol == "hysteria2" then - protocol = "HY2" - elseif protocol == "anytls" then - protocol = "AnyTLS" - elseif protocol == "ssh" then - protocol = "SSH" - else - protocol = protocol:gsub("^%l",string.upper) - end - if type == "sing-box" then type = "Sing-Box" end - type = type .. " " .. protocol - end - local address = m:get(n, "address") or "" - local port = m:get(n, "port") or "" - local port_s = (port ~= "") and port or m:get(n, "hysteria_hop") or m:get(n, "hysteria2_hop") or "" - str = str .. translate(type) .. ":" .. remarks - if address ~= "" and port_s ~= "" then - port_s = port_s:gsub(":", "-") - if show_node_info == "1" then - if datatypes.ip6addr(address) then - str = str .. string.format("([%s]:%s)", address, port_s) - else - str = str .. string.format("(%s:%s)", address, port_s) - end - end - end - str = str .. string.format("", appname, n, address) - str = str .. string.format("", appname, n, port) - return str -end - ----- Ping -o = s:option(DummyValue, "ping", "Ping") -o.width = "8%" -o.rawhtml = true -o.cfgvalue = function(t, n) - local result = "---" - if auto_detection_time ~= "icmp" then - result = string.format('%s', n, translate("Test")) - else - result = string.format('---', n) - end - return result -end - ----- TCP Ping -o = s:option(DummyValue, "tcping", "TCPing") -o.width = "8%" -o.rawhtml = true -o.cfgvalue = function(t, n) - local result = "---" - if auto_detection_time ~= "tcping" then - result = string.format('%s', n, translate("Test")) - else - result = string.format('---', n) - end - return result -end - -o = s:option(DummyValue, "_url_test", translate("URL Test")) -o.width = "8%" -o.rawhtml = true -o.cfgvalue = function(t, n) - return string.format('%s', n, translate("Test")) -end - m:append(Template(appname .. "/node_list/node_list")) return m diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua index a604594b36..e7157ec38d 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua @@ -202,7 +202,7 @@ o.cfgvalue = function(t, n) str = str ~= "" and "
" .. str or "" local num = 0 m.uci:foreach(appname, "nodes", function(s) - if s["add_from"] ~= "" and s["add_from"] == remark then + if s["group"] ~= "" and s["group"] == remark then num = num + 1 end end) diff --git a/small/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm b/small/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm index 5acf53fb4b..a91103c6b5 100644 --- a/small/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm +++ b/small/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm @@ -79,6 +79,10 @@ local api = require "luci.passwall.api" } } + function add_new_node() { + window.location.href = '<%=api.url("add_node")%>?redirect=1'; + } + //]]> @@ -99,7 +103,7 @@ local api = require "luci.passwall.api"
- + @@ -107,7 +111,6 @@ local api = require "luci.passwall.api" -
diff --git a/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm index 6ab4cd67ab..268d033742 100644 --- a/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm +++ b/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm @@ -44,12 +44,48 @@ table td, .table .td { } + +<% if api.is_js_luci() then -%> + +<%- end %> + - var edit_btn = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-button cbi-button-edit"); - for (var i = 0; i < edit_btn.length; i++) { - try { - var onclick_str = edit_btn[i].getAttribute("onclick"); - var id = onclick_str.substring(onclick_str.lastIndexOf('/') + 1, onclick_str.length - 1); - var td = edit_btn[i].parentNode; - var new_div = ""; - //添加"勾选"框 - new_div += '  '; - //添加"置顶"按钮 - new_div += '  '; - //添加"应用"按钮 - new_div += '  '; - //添加"复制"按钮 - new_div += '  '; - td.innerHTML = new_div + td.innerHTML; + - var obj = {}; - obj.id = id; - obj.type = document.getElementById("cbid.passwall." + id + ".type").value; - var address_dom = document.getElementById("cbid.passwall." + id + ".address"); - var port_dom = document.getElementById("cbid.passwall." + id + ".port"); - if (address_dom && port_dom) { - obj.address = address_dom.value; - obj.port = port_dom.value; + + +
+
+ + @@ -99,7 +103,7 @@ local api = require "luci.passwall2.api"
- + @@ -107,7 +111,6 @@ local api = require "luci.passwall2.api" -
diff --git a/small/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm b/small/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm index c694d4f655..e9965092e7 100644 --- a/small/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm +++ b/small/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm @@ -61,11 +61,46 @@ table td, .table .td { } +<% if api.is_js_luci() then -%> + +<%- end %> + + + + + + + +
+
+ + diff --git a/small/luci-app-passwall2/po/zh-cn/passwall2.po b/small/luci-app-passwall2/po/zh-cn/passwall2.po index 4d2711f592..e547c26543 100644 --- a/small/luci-app-passwall2/po/zh-cn/passwall2.po +++ b/small/luci-app-passwall2/po/zh-cn/passwall2.po @@ -1836,3 +1836,9 @@ msgstr "如留空,则使用随机版本。" msgid "The configured type also applies to the core specified when manually importing nodes." msgstr "配置的类型同样适用于手动导入节点时所指定的核心程序。" + +msgid "Group Name" +msgstr "分组名" + +msgid "Using..." +msgstr "使用中。" diff --git a/small/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 b/small/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 index cb52b9cc32..676dad41b5 100755 --- a/small/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 +++ b/small/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 @@ -35,13 +35,13 @@ EOF chmod +x /usr/share/passwall2/*.sh -[ -e "/etc/config/passwall2_show" ] && rm -rf /etc/config/passwall2_show - [ "$(uci -q get passwall2.@global_xray[0].sniffing)" == "1" ] && [ "$(uci -q get passwall2.@global_xray[0].route_only)" != "1" ] && uci -q set passwall2.@global_xray[0].sniffing_override_dest=1 uci -q delete passwall2.@global_xray[0].sniffing uci -q delete passwall2.@global_xray[0].route_only uci -q commit passwall2 +sed -i "s#add_from#group#g" /etc/config/passwall2 2>/dev/null + rm -f /tmp/luci-indexcache rm -rf /tmp/luci-modulecache/ killall -HUP rpcd 2>/dev/null diff --git a/small/luci-app-passwall2/root/usr/share/passwall2/app.sh b/small/luci-app-passwall2/root/usr/share/passwall2/app.sh index 474560f7f6..feb0fbed23 100755 --- a/small/luci-app-passwall2/root/usr/share/passwall2/app.sh +++ b/small/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -1343,7 +1343,7 @@ stop() { # 结束 SS 插件进程 # kill_all xray-plugin v2ray-plugin obfs-local shadow-tls local pid_file pid - find "$TMP_PATH" -type f -name '*_plugin.pid' | while read -r pid_file; do + find "$TMP_PATH" -type f -name '*_plugin.pid' 2>/dev/null | while read -r pid_file; do read -r pid < "$pid_file" if [ -n "$pid" ]; then kill -9 "$pid" >/dev/null 2>&1 diff --git a/small/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/small/luci-app-passwall2/root/usr/share/passwall2/iptables.sh index 44cc493460..6e53426535 100755 --- a/small/luci-app-passwall2/root/usr/share/passwall2/iptables.sh +++ b/small/luci-app-passwall2/root/usr/share/passwall2/iptables.sh @@ -358,7 +358,7 @@ load_acl() { ipset -! create $ipset_white6 nethash family inet6 maxelem 1048576 #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${node} shunt_list4 shunt_list6 ${write_ipset_direct} ${ipset_white} ${ipset_white6} + gen_shunt_list "${node}" shunt_list4 shunt_list6 ${write_ipset_direct} ${ipset_white} ${ipset_white6} fi } @@ -671,7 +671,7 @@ filter_direct_node_list() { } add_firewall_rule() { - echolog "开始加载防火墙规则..." + echolog "开始加载 iptables 防火墙规则..." ipset -! create $IPSET_LOCAL nethash maxelem 1048576 ipset -! create $IPSET_LAN nethash maxelem 1048576 ipset -! create $IPSET_VPS nethash maxelem 1048576 @@ -735,7 +735,7 @@ add_firewall_rule() { ipset -! create $ipset_global_white6 nethash family inet6 maxelem 1048576 timeout 259200 #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${NODE} SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${ipset_global_white} ${ipset_global_white6} + gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${ipset_global_white} ${ipset_global_white6} # 过滤所有节点IP filter_vpsip > /dev/null 2>&1 & @@ -772,31 +772,28 @@ add_firewall_rule() { else $ipt_n -I PREROUTING -j PSW2_DNS fi - - $ipt_m -N PSW2_DIVERT - $ipt_m -A PSW2_DIVERT -j MARK --set-mark 1 - $ipt_m -A PSW2_DIVERT -j ACCEPT $ipt_m -N PSW2_RULE $ipt_m -A PSW2_RULE -j CONNMARK --restore-mark $ipt_m -A PSW2_RULE -m mark --mark 0x1 -j RETURN - $ipt_m -A PSW2_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 - $ipt_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 + $ipt_m -A PSW2_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 + $ipt_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 $ipt_m -A PSW2_RULE -j CONNMARK --save-mark $ipt_m -N PSW2 $ipt_m -A PSW2 $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW2 $(dst $IPSET_VPS) -j RETURN + $ipt_m -A PSW2 -m conntrack --ctdir REPLY -j RETURN [ ! -z "${WAN_IP}" ] && $ipt_m -A PSW2 $(comment "WAN_IP_RETURN") -d "${WAN_IP}" -j RETURN unset WAN_IP insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW2" - insert_rule_before "$ipt_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT" $ipt_m -N PSW2_OUTPUT $ipt_m -A PSW2_OUTPUT $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW2_OUTPUT $(dst $IPSET_VPS) -j RETURN + $ipt_m -A PSW2_OUTPUT -m conntrack --ctdir REPLY -j RETURN [ -n "$AUTO_DNS" ] && { for auto_dns in $(echo $AUTO_DNS | tr ',' ' '); do local dns_address=$(echo $auto_dns | awk -F '#' '{print $1}') @@ -829,33 +826,30 @@ add_firewall_rule() { else $ip6t_n -I PREROUTING -j PSW2_DNS fi - - $ip6t_m -N PSW2_DIVERT - $ip6t_m -A PSW2_DIVERT -j MARK --set-mark 1 - $ip6t_m -A PSW2_DIVERT -j ACCEPT $ip6t_m -N PSW2_RULE $ip6t_m -A PSW2_RULE -j CONNMARK --restore-mark $ip6t_m -A PSW2_RULE -m mark --mark 0x1 -j RETURN - $ip6t_m -A PSW2_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 - $ip6t_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 + $ip6t_m -A PSW2_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 + $ip6t_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 $ip6t_m -A PSW2_RULE -j CONNMARK --save-mark $ip6t_m -N PSW2 $ip6t_m -A PSW2 $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW2 $(dst $IPSET_VPS6) -j RETURN + $ip6t_m -A PSW2 -m conntrack --ctdir REPLY -j RETURN WAN6_IP=$(get_wan6_ip) [ ! -z "${WAN6_IP}" ] && $ip6t_m -A PSW2 $(comment "WAN6_IP_RETURN") -d ${WAN6_IP} -j RETURN unset WAN6_IP insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW2" - insert_rule_before "$ip6t_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT" $ip6t_m -N PSW2_OUTPUT $ip6t_m -A PSW2_OUTPUT -m mark --mark 0xff -j RETURN $ip6t_m -A PSW2_OUTPUT $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW2_OUTPUT $(dst $IPSET_VPS6) -j RETURN + $ip6t_m -A PSW2_OUTPUT -m conntrack --ctdir REPLY -j RETURN ip -6 rule add fwmark 1 table 100 ip -6 route add local ::/0 dev lo table 100 @@ -1000,7 +994,7 @@ del_firewall_rule() { $ipt -D $chain $index 2>/dev/null done done - for chain in "PSW2" "PSW2_OUTPUT" "PSW2_DIVERT" "PSW2_DNS" "PSW2_RULE"; do + for chain in "PSW2" "PSW2_OUTPUT" "PSW2_DNS" "PSW2_RULE"; do $ipt -F $chain 2>/dev/null $ipt -X $chain 2>/dev/null done @@ -1034,7 +1028,7 @@ gen_include() { [ -z "${_ipt}" ] && return echo "*$2" - ${_ipt}-save -t $2 | grep "PSW2" | grep -v "\-j PSW2$" | grep -v "socket \-j PSW2_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + ${_ipt}-save -t $2 | grep "PSW2" | grep -v "\-j PSW2$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" echo 'COMMIT' } local __ipt="" @@ -1050,7 +1044,6 @@ gen_include() { [ -z "${is_tproxy}" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW2") \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW2") - \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT") WAN_IP=\$(${MY_PATH} get_wan_ip) @@ -1078,7 +1071,6 @@ gen_include() { [ "$accept_icmpv6" = "1" ] && $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW2 \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW2") - \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT") PR_INDEX=\$(${MY_PATH} RULE_LAST_INDEX "$ip6t_m" PSW2 WAN6_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/small/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/small/luci-app-passwall2/root/usr/share/passwall2/nftables.sh index 4d6b946d1b..2785e41439 100755 --- a/small/luci-app-passwall2/root/usr/share/passwall2/nftables.sh +++ b/small/luci-app-passwall2/root/usr/share/passwall2/nftables.sh @@ -382,7 +382,7 @@ load_acl() { gen_nftset $nftset_white6 ipv6_addr 3d 3d #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${node} shunt_list4 shunt_list6 ${write_ipset_direct} ${nftset_white} ${nftset_white6} + gen_shunt_list "${node}" shunt_list4 shunt_list6 ${write_ipset_direct} ${nftset_white} ${nftset_white6} fi } @@ -701,7 +701,7 @@ filter_direct_node_list() { } add_firewall_rule() { - echolog "开始加载防火墙规则..." + echolog "开始加载 nftables 防火墙规则..." gen_nft_tables gen_nftset $NFTSET_LOCAL ipv4_addr 0 "-1" gen_nftset $NFTSET_LAN ipv4_addr 0 "-1" $(gen_lanlist) @@ -749,7 +749,7 @@ add_firewall_rule() { gen_nftset $nftset_global_white6 ipv6_addr 0 0 #分流规则的IP列表(使用分流节点时导入) - gen_shunt_list ${NODE} SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${nftset_global_white} ${nftset_global_white6} + gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6 ${WRITE_IPSET_DIRECT} ${nftset_global_white} ${nftset_global_white6} # 过滤所有节点IP filter_vpsip > /dev/null 2>&1 & @@ -771,10 +771,6 @@ add_firewall_rule() { nft_output_chain="PSW2_OUTPUT_MANGLE" fi - nft "add chain $NFTABLE_NAME PSW2_DIVERT" - nft "flush chain $NFTABLE_NAME PSW2_DIVERT" - nft "add rule $NFTABLE_NAME PSW2_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept" - nft "add chain $NFTABLE_NAME PSW2_DNS" nft "flush chain $NFTABLE_NAME PSW2_DNS" if [ $(config_t_get global dns_redirect "1") = "0" ]; then @@ -790,8 +786,8 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW2_RULE" nft "add rule $NFTABLE_NAME PSW2_RULE meta mark set ct mark counter" nft "add rule $NFTABLE_NAME PSW2_RULE meta mark 1 counter return" - nft "add rule $NFTABLE_NAME PSW2_RULE tcp flags &(fin|syn|rst|ack) == syn meta mark set mark and 0x0 xor 0x1 counter" - nft "add rule $NFTABLE_NAME PSW2_RULE meta l4proto udp ct state new meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW2_RULE tcp flags syn meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW2_RULE meta l4proto udp ct state new,related meta mark set mark and 0x0 xor 0x1 counter" nft "add rule $NFTABLE_NAME PSW2_RULE ct mark set mark counter" #ipv4 tproxy mode and udp @@ -799,11 +795,13 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW2_MANGLE" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ct direction reply counter return" [ -n "$AUTO_DNS" ] && { for auto_dns in $(echo $AUTO_DNS | tr ',' ' '); do local dns_address=$(echo $auto_dns | awk -F '#' '{print $1}') @@ -817,7 +815,6 @@ add_firewall_rule() { # jump chains nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol udp counter jump PSW2_MANGLE" [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol tcp counter jump PSW2_MANGLE" - insert_rule_before "$NFTABLE_NAME" "mangle_prerouting" "PSW2_MANGLE" "counter jump PSW2_DIVERT" #ipv4 tcp redirect mode [ -z "${is_tproxy}" ] && { @@ -865,11 +862,13 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW2_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ct direction reply counter return" nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta mark 0xff counter return" # jump chains @@ -1067,7 +1066,7 @@ gen_include() { local __nft=" " __nft=$(cat <<- EOF - [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW2_DIVERT)" ] && nft -f ${nft_chain_file} + [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW2)" ] && nft -f ${nft_chain_file} [ -z "${is_tproxy}" ] && { PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "$NFTABLE_NAME" PSW2_NAT WAN_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/small/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/small/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index c2191e189f..384e65db05 100755 --- a/small/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/small/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -444,12 +444,12 @@ local function get_subscribe_info(cfgid, value) end -- 处理数据 -local function processData(szType, content, add_mode, add_from) - --log(content, add_mode, add_from) +local function processData(szType, content, add_mode, group) + --log(content, add_mode, group) local result = { timeout = 60, add_mode = add_mode, --0为手动配置,1为导入,2为订阅 - add_from = add_from + group = group } --ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0) if szType == 'ssr' then @@ -1544,14 +1544,14 @@ local function curl(url, file, ua, mode) return tonumber(result) end -local function truncate_nodes(add_from) +local function truncate_nodes(group) for _, config in pairs(CONFIG) do if config.currentNodes and #config.currentNodes > 0 then local newNodes = {} local removeNodesSet = {} for k, v in pairs(config.currentNodes) do if v.currentNode and v.currentNode.add_mode == "2" then - if (not add_from) or (add_from and add_from == v.currentNode.add_from) then + if (not group) or (group and group == v.currentNode.group) then removeNodesSet[v.currentNode[".name"]] = true end end @@ -1566,7 +1566,7 @@ local function truncate_nodes(add_from) end else if config.currentNode and config.currentNode.add_mode == "2" then - if (not add_from) or (add_from and add_from == config.currentNode.add_from) then + if (not group) or (group and group == config.currentNode.group) then if config.delete then config.delete(config) elseif config.set then @@ -1578,13 +1578,13 @@ local function truncate_nodes(add_from) end uci:foreach(appname, "nodes", function(node) if node.add_mode == "2" then - if (not add_from) or (add_from and add_from == node.add_from) then + if (not group) or (group and group == node.group) then uci:delete(appname, node['.name']) end end end) uci:foreach(appname, "subscribe_list", function(o) - if (not add_from) or add_from == o.remark then + if (not group) or group == o.remark then uci:delete(appname, o['.name'], "md5") end end) @@ -1725,7 +1725,7 @@ local function update_node(manual) if manual == 0 and next(group) then uci:foreach(appname, "nodes", function(node) -- 如果未发现新节点或手动导入的节点就不要删除了... - if node.add_mode == "2" and (node.add_from and group[node.add_from] == true) then + if node.add_mode == "2" and (node.group and group[node.group] == true) then uci:delete(appname, node['.name']) end end) @@ -1802,7 +1802,7 @@ local function update_node(manual) luci.sys.call("/etc/init.d/" .. appname .. " restart > /dev/null 2>&1 &") end -local function parse_link(raw, add_mode, add_from, cfgid) +local function parse_link(raw, add_mode, group, cfgid) if raw and #raw > 0 then local nodes, szType local node_list = {} @@ -1838,17 +1838,17 @@ local function parse_link(raw, add_mode, add_from, cfgid) xpcall(function () local result if szType == 'ssd' then - result = processData(szType, v, add_mode, add_from) + result = processData(szType, v, add_mode, group) elseif not szType then local node = api.trim(v) local dat = split(node, "://") if dat and dat[1] and dat[2] then if dat[1] == 'vmess' or dat[1] == 'ssr' then local link = api.trim(dat[2]:gsub("#.*$", "")) - result = processData(dat[1], base64Decode(link), add_mode, add_from) + result = processData(dat[1], base64Decode(link), add_mode, group) else local link = dat[2]:gsub("&", "&"):gsub("%s*#%s*", "#") -- 一些奇葩的链接用"&"当做"&","#"前后带空格 - result = processData(dat[1], link, add_mode, add_from) + result = processData(dat[1], link, add_mode, group) end end else @@ -1879,14 +1879,14 @@ local function parse_link(raw, add_mode, add_from, cfgid) end if #node_list > 0 then nodeResult[#nodeResult + 1] = { - remark = add_from, + remark = group, list = node_list } end - log('成功解析【' .. add_from .. '】节点数量: ' .. #node_list) + log('成功解析【' .. group .. '】节点数量: ' .. #node_list) else if add_mode == "2" then - log('获取到的【' .. add_from .. '】订阅内容为空,可能是订阅地址无效,或是网络问题,请诊断!') + log('获取到的【' .. group .. '】订阅内容为空,可能是订阅地址无效,或是网络问题,请诊断!') end end end diff --git a/small/v2ray-geodata/Makefile b/small/v2ray-geodata/Makefile index b11a32339b..62dc2800c0 100644 --- a/small/v2ray-geodata/Makefile +++ b/small/v2ray-geodata/Makefile @@ -12,13 +12,13 @@ PKG_MAINTAINER:=Tianling Shen include $(INCLUDE_DIR)/package.mk -GEOIP_VER:=202510050144 +GEOIP_VER:=202511050144 GEOIP_FILE:=geoip.dat.$(GEOIP_VER) define Download/geoip URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/ URL_FILE:=geoip.dat FILE:=$(GEOIP_FILE) - HASH:=c23ac8343e9796f8cc8b670c3aeb6df6d03d4e8914437a409961477f6b226098 + HASH:=2445b44d9ae3ab9a867c9d1e0e244646c4c378622e14b9afaf3658ecf46a40b9 endef GEOSITE_VER:=20251101070148 diff --git a/v2rayn/v2rayN/Directory.Packages.props b/v2rayn/v2rayN/Directory.Packages.props index b9caf59f88..1e4f9e338a 100644 --- a/v2rayn/v2rayN/Directory.Packages.props +++ b/v2rayn/v2rayN/Directory.Packages.props @@ -14,7 +14,7 @@ - + diff --git a/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs b/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs index 7469f35159..449592a700 100644 --- a/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs @@ -45,7 +45,7 @@ public class CertPemManager "2530CC8E98321502BAD96F9B1FBA1B099E2D299E0F4548BB914F363BC0D4531F", // Izenpe.com "45140B3247EB9CC8C5B4F0D7B53091F73292089E6E5A63E2749DD3ACA9198EDA", // Go Daddy Root Certificate Authority - G2 "2CE1CB0BF9D2F9E102993FBE215152C3B2DD0CABDE1C68E5319B839154DBB7F5", // Starfield Root Certificate Authority - G2 - "568D6905A2C88708A4B3025190EDCFEDB1974A606A13C6E5290FCB2AE63EDAB5", // Starfield Services Root Certificate Authority - G2 + "568D6905A2C88708A4B3025190EDCFEDB1974A606A13C6E5290FCB2AE63EDAB5", // Starfield Services Root Certificate Authority - G2 "0376AB1D54C5F9803CE4B2E201A0EE7EEF7B57B636E8A93C9B8D4860C96F5FA7", // AffirmTrust Commercial "0A81EC5A929777F145904AF38D5D509F66B5E2C58FCDB531058B0E17F3F0B41B", // AffirmTrust Networking "70A73F7F376B60074248904534B11482D5BF0E698ECC498DF52577EBF2E93B9A", // AffirmTrust Premium @@ -95,11 +95,11 @@ public class CertPemManager "18CE6CFE7BF14E60B2E347B8DFE868CB31D02EBB3ADA271569F50343B46DB3A4", // Amazon Root CA 3 "E35D28419ED02025CFA69038CD623962458DA5C695FBDEA3C22B0BFB25897092", // Amazon Root CA 4 "A1A86D04121EB87F027C66F53303C28E5739F943FC84B38AD6AF009035DD9457", // D-TRUST Root CA 3 2013 - "46EDC3689046D53A453FB3104AB80DCAEC658B2660EA1629DD7E867990648716", // TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 + "46EDC3689046D53A453FB3104AB80DCAEC658B2660EA1629DD7E867990648716", // TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 "BFFF8FD04433487D6A8AA60C1A29767A9FC2BBB05E420F713A13B992891D3893", // GDCA TrustAUTH R5 ROOT "85666A562EE0BE5CE925C1D8890A6F76A87EC16D4D7D5F29EA7419CF20123B69", // SSL.com Root Certification Authority RSA "3417BB06CC6007DA1B961C920B8AB4CE3FAD820E4AA30B9ACBC4A74EBDCEBC65", // SSL.com Root Certification Authority ECC - "2E7BF16CC22485A7BBE2AA8696750761B0AE39BE3B2FE9D0CC6D4EF73491425C", // SSL.com EV Root Certification Authority RSA R2 + "2E7BF16CC22485A7BBE2AA8696750761B0AE39BE3B2FE9D0CC6D4EF73491425C", // SSL.com EV Root Certification Authority RSA R2 "22A2C1F7BDED704CC1E701B5F408C310880FE956B5DE2A4A44F99C873A25A7C8", // SSL.com EV Root Certification Authority ECC "2CABEAFE37D06CA22ABA7391C0033D25982952C453647349763A3AB5AD6CCF69", // GlobalSign Root CA - R6 "8560F91C3624DABA9570B5FEA0DBE36FF11A8323BE9486854FB3F34A5571198D", // OISTE WISeKey Global Root GC CA @@ -112,13 +112,13 @@ public class CertPemManager "BC4D809B15189D78DB3E1D8CF4F9726A795DA1643CA5F1358E1DDB0EDC0D7EB3", // emSign ECC Root CA - C3 "5A2FC03F0C83B090BBFA40604B0988446C7636183DF9846E17101A447FB8EFD6", // Hongkong Post Root CA 3 "DB3517D1F6732A2D5AB97C533EC70779EE3270A62FB4AC4238372460E6F01E88", // Entrust Root Certification Authority - G4 - "358DF39D764AF9E1B766E9C972DF352EE15CFAC227AF6AD1D70E8E4A6EDCBA02", // Microsoft ECC Root Certificate Authority 2017 - "C741F70F4B2A8D88BF2E71C14122EF53EF10EBA0CFA5E64CFA20F418853073E0", // Microsoft RSA Root Certificate Authority 2017 + "358DF39D764AF9E1B766E9C972DF352EE15CFAC227AF6AD1D70E8E4A6EDCBA02", // Microsoft ECC Root Certificate Authority 2017 + "C741F70F4B2A8D88BF2E71C14122EF53EF10EBA0CFA5E64CFA20F418853073E0", // Microsoft RSA Root Certificate Authority 2017 "BEB00B30839B9BC32C32E4447905950641F26421B15ED089198B518AE2EA1B99", // e-Szigno Root CA 2017 "657CFE2FA73FAA38462571F332A2363A46FCE7020951710702CDFBB6EEDA3305", // certSIGN Root CA G2 "97552015F5DDFC3C8788C006944555408894450084F100867086BC1A2BB58DC8", // Trustwave Global Certification Authority - "945BBC825EA554F489D1FD51A73DDF2EA624AC7019A05205225C22A78CCFA8B4", // Trustwave Global ECC P256 Certification Authority - "55903859C8C0C3EBB8759ECE4E2557225FF5758BBD38EBD48276601E1BD58097", // Trustwave Global ECC P384 Certification Authority + "945BBC825EA554F489D1FD51A73DDF2EA624AC7019A05205225C22A78CCFA8B4", // Trustwave Global ECC P256 Certification Authority + "55903859C8C0C3EBB8759ECE4E2557225FF5758BBD38EBD48276601E1BD58097", // Trustwave Global ECC P384 Certification Authority "88F438DCF8FFD1FA8F429115FFE5F82AE1E06E0C70C375FAAD717B34A49E7265", // NAVER Global Root Certification Authority "554153B13D2CF9DDB753BFBE1A4E0AE08D0AA4187058FE60A2B862B2E4B87BCB", // AC RAIZ FNMT-RCM SERVIDORES SEGUROS "319AF0A7729E6F89269C131EA6A3A16FCD86389FDCAB3C47A4A675C161A3F974", // GlobalSign Secure Mail Root R45 @@ -161,8 +161,8 @@ public class CertPemManager "48E1CF9E43B688A51044160F46D773B8277FE45BEAAD0E4DF90D1974382FEA99", // LAWtrust Root CA2 (4096) "22D9599234D60F1D4BC7C7E96F43FA555B07301FD475175089DAFB8C25E477B3", // Sectigo Public Email Protection Root E46 "D5917A7791EB7CF20A2E57EB98284A67B28A57E89182DA53D546678C9FDE2B4F", // Sectigo Public Email Protection Root R46 - "C90F26F0FB1B4018B22227519B5CA2B53E2CA5B3BE5CF18EFE1BEF47380C5383", // Sectigo Public Server Authentication Root E46 - "7BB647A62AEEAC88BF257AA522D01FFEA395E0AB45C73F93F65654EC38F25A06", // Sectigo Public Server Authentication Root R46 + "C90F26F0FB1B4018B22227519B5CA2B53E2CA5B3BE5CF18EFE1BEF47380C5383", // Sectigo Public Server Authentication Root E46 + "7BB647A62AEEAC88BF257AA522D01FFEA395E0AB45C73F93F65654EC38F25A06", // Sectigo Public Server Authentication Root R46 "8FAF7D2E2CB4709BB8E0B33666BF75A5DD45B5DE480F8EA8D4BFE6BEBC17F2ED", // SSL.com TLS RSA Root CA 2022 "C32FFD9F46F936D16C3673990959434B9AD60AAFBB9E7CF33654F144CC1BA143", // SSL.com TLS ECC Root CA 2022 "AD7DD58D03AEDB22A30B5084394920CE12230C2D8017AD9B81AB04079BDD026B", // SSL.com Client ECC Root CA 2022 @@ -202,14 +202,17 @@ public class CertPemManager /// /// Get certificate in PEM format from a server with CA pinning validation /// - public async Task GetCertPemAsync(string target, string serverName) + public async Task<(string?, string?)> GetCertPemAsync(string target, string serverName, int timeout = 10) { try { var (domain, _, port, _) = Utils.ParseUrl(target); + using var cts = new CancellationTokenSource(); + cts.CancelAfter(TimeSpan.FromSeconds(timeout)); + using var client = new TcpClient(); - await client.ConnectAsync(domain, port > 0 ? port : 443); + await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token); using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); @@ -218,31 +221,39 @@ public class CertPemManager var remote = ssl.RemoteCertificate; if (remote == null) { - return null; + return (null, null); } var leaf = new X509Certificate2(remote); - return ExportCertToPem(leaf); + return (ExportCertToPem(leaf), null); + } + catch (OperationCanceledException) + { + Logging.SaveLog(_tag, new TimeoutException($"Connection timeout after {timeout} seconds")); + return (null, $"Connection timeout after {timeout} seconds"); } catch (Exception ex) { Logging.SaveLog(_tag, ex); - return null; + return (null, ex.Message); } } /// /// Get certificate chain in PEM format from a server with CA pinning validation /// - public async Task> GetCertChainPemAsync(string target, string serverName) + public async Task<(List, string?)> GetCertChainPemAsync(string target, string serverName, int timeout = 10) { + var pemList = new List(); try { - var pemList = new List(); var (domain, _, port, _) = Utils.ParseUrl(target); + using var cts = new CancellationTokenSource(); + cts.CancelAfter(TimeSpan.FromSeconds(timeout)); + using var client = new TcpClient(); - await client.ConnectAsync(domain, port > 0 ? port : 443); + await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token); using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); @@ -250,7 +261,7 @@ public class CertPemManager if (ssl.RemoteCertificate is not X509Certificate2 certChain) { - return pemList; + return (pemList, null); } var chain = new X509Chain(); @@ -262,12 +273,17 @@ public class CertPemManager pemList.Add(pem); } - return pemList; + return (pemList, null); + } + catch (OperationCanceledException) + { + Logging.SaveLog(_tag, new TimeoutException($"Connection timeout after {timeout} seconds")); + return (pemList, $"Connection timeout after {timeout} seconds"); } catch (Exception ex) { Logging.SaveLog(_tag, ex); - return new List(); + return (pemList, ex.Message); } } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs index 121bf5daae..221d28d0f7 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs @@ -146,7 +146,8 @@ public class AddServerViewModel : MyReactiveObject { domain += $":{SelectedSource.Port}"; } - Cert = await CertPemManager.Instance.GetCertPemAsync(domain, serverName); + (Cert, _certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName); + UpdateCertTip(); } private async Task FetchCertChain() @@ -176,7 +177,8 @@ public class AddServerViewModel : MyReactiveObject { domain += $":{SelectedSource.Port}"; } - var certs = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName); + (var certs, _certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName); + UpdateCertTip(); Cert = string.Join("\n", certs); } } diff --git a/v2rayu/V2rayU/ConfigWindow.swift b/v2rayu/V2rayU/ConfigWindow.swift index 140e564d44..5403eba949 100755 --- a/v2rayu/V2rayU/ConfigWindow.swift +++ b/v2rayu/V2rayU/ConfigWindow.swift @@ -369,9 +369,9 @@ class ConfigWindowController: NSWindowController, NSWindowDelegate, NSTabViewDel v2rayConfig.securityTls.serverName = self.streamTlsServerName.stringValue let streamTlsAlpn = self.streamTlsAlpn.stringValue if streamTlsAlpn.count != 0 { - v2rayConfig.securityTls.alpn = [streamTlsAlpn] + v2rayConfig.securityTls.alpn = streamTlsAlpn.components(separatedBy: ",").map { $0.trimmingCharacters(in: CharacterSet(charactersIn: " \"")) } } else { - v2rayConfig.securityTls.alpn = [] + v2rayConfig.securityTls.alpn = ["h2", "http/1.1"] } // reality v2rayConfig.securityReality.serverName = self.streamRealityServerName.stringValue @@ -511,7 +511,7 @@ class ConfigWindowController: NSWindowController, NSWindowDelegate, NSTabViewDel self.streamSecurity.selectItem(withTitle: v2rayConfig.streamSecurity) self.streamTlsAllowInsecure.intValue = v2rayConfig.securityTls.allowInsecure ? 1 : 0 self.streamTlsServerName.stringValue = v2rayConfig.securityTls.serverName - self.streamTlsAlpn.stringValue = v2rayConfig.securityTls.alpn.count > 0 ? v2rayConfig.securityTls.alpn[0] : "" + self.streamTlsAlpn.stringValue = v2rayConfig.securityTls.alpn.map { "\"\($0)\"" }.joined(separator: ", ") // reality self.streamRealityServerName.stringValue = v2rayConfig.securityReality.serverName diff --git a/yt-dlp/yt_dlp/extractor/youtube/_base.py b/yt-dlp/yt_dlp/extractor/youtube/_base.py index 2f7b82cd7c..9ecce15553 100644 --- a/yt-dlp/yt_dlp/extractor/youtube/_base.py +++ b/yt-dlp/yt_dlp/extractor/youtube/_base.py @@ -331,7 +331,7 @@ INNERTUBE_CLIENTS = { 'INNERTUBE_CONTEXT': { 'client': { 'clientName': 'TVHTML5', - 'clientVersion': '4', + 'clientVersion': '5.20251105', 'userAgent': 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/Version', }, },