From 5782a637029ee629ade7ae107946fe7fa7b48a9e Mon Sep 17 00:00:00 2001 From: "github-action[bot]" Date: Thu, 27 Nov 2025 19:38:26 +0100 Subject: [PATCH] Update On Thu Nov 27 19:38:25 CET 2025 --- .github/update.log | 1 + clash-nyanpasu/backend/Cargo.lock | 178 +++++----- clash-nyanpasu/frontend/nyanpasu/package.json | 2 +- clash-nyanpasu/manifest/version.json | 4 +- clash-nyanpasu/pnpm-lock.yaml | 10 +- filebrowser/frontend/pnpm-lock.yaml | 44 +-- lede/target/linux/x86/64/config-6.12 | 1 + mieru/Makefile | 2 +- .../package/mieru/amd64/debian/DEBIAN/control | 2 +- .../build/package/mieru/amd64/rpm/mieru.spec | 2 +- .../package/mieru/arm64/debian/DEBIAN/control | 2 +- .../build/package/mieru/arm64/rpm/mieru.spec | 2 +- .../package/mita/amd64/debian/DEBIAN/control | 2 +- mieru/build/package/mita/amd64/rpm/mita.spec | 2 +- .../package/mita/arm64/debian/DEBIAN/control | 2 +- mieru/build/package/mita/arm64/rpm/mita.spec | 2 +- mieru/docs/server-install.md | 16 +- mieru/docs/server-install.zh_CN.md | 16 +- mieru/pkg/common/ascii.go | 2 +- mieru/pkg/protocol/mux.go | 1 - mieru/pkg/protocol/session.go | 129 +++---- mieru/pkg/protocol/underlay_base.go | 4 - mieru/pkg/protocol/underlay_packet.go | 317 ++++++++---------- mieru/pkg/version/current.go | 2 +- mieru/test/deploy/packetdrop/libtest.sh | 14 + mieru/test/deploy/packetdrop/test_tcp.sh | 8 + mieru/test/deploy/packetdrop/test_udp.sh | 8 + openwrt-packages/luci-app-amlogic/Makefile | 2 +- .../root/usr/sbin/openwrt-install-amlogic | 21 +- .../root/usr/sbin/openwrt-update-rockchip | 8 + openwrt-passwall/luci-app-passwall/Makefile | 2 +- .../model/cbi/passwall/client/type/ray.lua | 10 +- .../luci-app-passwall/luasrc/passwall/api.lua | 14 +- .../luasrc/passwall/util_xray.lua | 2 +- .../view/passwall/node_list/link_add_node.htm | 2 +- .../view/passwall/node_list/node_list.htm | 39 +-- .../root/usr/share/passwall/subscribe.lua | 2 +- shadowsocks-rust/Cargo.lock | 75 ++--- small/gn/Makefile | 2 +- small/luci-app-passwall/Makefile | 2 +- .../resources/view/passwall/Sortable.min.js | 2 + .../cbi/passwall/client/node_subscribe.lua | 2 +- .../model/cbi/passwall/client/type/ray.lua | 10 +- .../luci-app-passwall/luasrc/passwall/api.lua | 14 +- .../luasrc/passwall/util_xray.lua | 2 +- .../view/passwall/node_list/link_add_node.htm | 2 +- .../view/passwall/node_list/node_list.htm | 113 +++++-- small/luci-app-passwall/po/zh-cn/passwall.po | 3 + .../root/usr/share/passwall/subscribe.lua | 6 +- small/v2ray-geodata/Makefile | 4 +- v2rayn/.github/workflows/build-linux.yml | 6 +- .../v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 11 +- .../v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 7 +- v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx | 7 +- v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx | 5 +- v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx | 5 +- v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx | 5 +- .../v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 5 +- .../v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 7 +- .../Views/AddGroupServerWindow.axaml | 2 +- .../v2rayN/Views/AddGroupServerWindow.xaml | 2 +- .../com/v2ray/ang/service/TProxyService.kt | 5 +- .../app/src/main/res/values/arrays.xml | 2 +- .../app/src/main/res/xml/pref_settings.xml | 2 +- xray-core/app/dns/config.pb.go | 177 +++++----- xray-core/app/dns/config.proto | 4 +- xray-core/app/dns/dns.go | 12 +- xray-core/go.mod | 2 +- xray-core/go.sum | 4 +- xray-core/infra/conf/dns.go | 8 +- xray-core/infra/conf/dns_test.go | 3 +- 71 files changed, 748 insertions(+), 647 deletions(-) create mode 100644 small/luci-app-passwall/htdocs/luci-static/resources/view/passwall/Sortable.min.js diff --git a/.github/update.log b/.github/update.log index 6a306fa768..89f535f361 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1194,3 +1194,4 @@ Update On Sun Nov 23 19:36:55 CET 2025 Update On Mon Nov 24 19:40:17 CET 2025 Update On Tue Nov 25 19:40:43 CET 2025 Update On Wed Nov 26 19:35:47 CET 2025 +Update On Thu Nov 27 19:38:17 CET 2025 diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index 126f6b8e46..21bb5bc13c 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -374,7 +374,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -549,7 +549,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -584,7 +584,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -633,7 +633,7 @@ checksum = "99e1aca718ea7b89985790c94aad72d77533063fe00bc497bb79a7c2dae6a661" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -898,7 +898,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.109", + "syn 2.0.111", "which 4.4.2", ] @@ -1099,7 +1099,7 @@ checksum = "9fd3f870829131332587f607a7ff909f1af5fc523fd1b192db55fbbdf52e8d3c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "synstructure", ] @@ -1237,7 +1237,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -1529,7 +1529,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -1763,7 +1763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d" dependencies = [ "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2053,7 +2053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2063,7 +2063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2104,7 +2104,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2115,7 +2115,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2206,7 +2206,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2227,7 +2227,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2237,7 +2237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2250,7 +2250,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2405,7 +2405,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2437,7 +2437,7 @@ checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2735,7 +2735,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2756,7 +2756,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2827,7 +2827,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -2948,7 +2948,7 @@ checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -3105,7 +3105,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -3255,7 +3255,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -3571,7 +3571,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -3833,7 +3833,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -4362,7 +4362,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -4464,7 +4464,7 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.9", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -4481,7 +4481,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.9", - "syn 2.0.109", + "syn 2.0.111", "url", ] @@ -4579,7 +4579,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -5173,7 +5173,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -5684,7 +5684,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -5746,7 +5746,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -5815,7 +5815,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -6471,7 +6471,7 @@ checksum = "05bbaa5b6b98826bb62b164406f703bee72c5287af9986f9c863fa8ea992b476" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -6513,7 +6513,7 @@ dependencies = [ "phf 0.13.1", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -6779,7 +6779,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -6927,7 +6927,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "unicase", ] @@ -6941,7 +6941,7 @@ dependencies = [ "phf_shared 0.13.1", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -7004,7 +7004,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -7182,7 +7182,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -7268,7 +7268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -7666,7 +7666,7 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -7875,7 +7875,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8083,7 +8083,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8227,7 +8227,7 @@ checksum = "d6185cf75117e20e62b1ff867b9518577271e58abe0037c40bb4794969355ab0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8238,7 +8238,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8273,7 +8273,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8335,7 +8335,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8383,7 +8383,7 @@ checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8775,7 +8775,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8899,7 +8899,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -8942,9 +8942,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.109" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -8968,7 +8968,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -9090,7 +9090,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -9210,7 +9210,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.9", - "syn 2.0.109", + "syn 2.0.111", "tauri-utils", "thiserror 2.0.17", "time", @@ -9228,7 +9228,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "tauri-codegen", "tauri-utils", ] @@ -9534,7 +9534,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -9703,7 +9703,7 @@ checksum = "451b374529930d7601b1eef8d32bc79ae870b6079b069401709c2a8bf9e75f36" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -9749,7 +9749,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -9760,7 +9760,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -9917,7 +9917,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -10121,26 +10121,26 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", "parking_lot", - "thiserror 1.0.69", + "thiserror 2.0.17", "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -10232,7 +10232,7 @@ version = "0.2.5" source = "git+https://github.com/Frando/tracing-test.git?rev=e81ec65#e81ec655a5ec5c4351104628b1b1ba694f80a1dc" dependencies = [ "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -10738,7 +10738,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "wasm-bindgen-shared", ] @@ -10773,7 +10773,7 @@ checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11055,7 +11055,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -11472,7 +11472,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -11483,7 +11483,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -11494,7 +11494,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -11505,7 +11505,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -12293,7 +12293,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "synstructure", ] @@ -12305,7 +12305,7 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "synstructure", ] @@ -12361,7 +12361,7 @@ checksum = "dc6821851fa840b708b4cbbaf6241868cabc85a2dc22f426361b0292bfc0b836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "zbus-lockstep", "zbus_xml", "zvariant", @@ -12376,7 +12376,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "zbus_names", "zvariant", "zvariant_utils", @@ -12424,7 +12424,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -12444,7 +12444,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "synstructure", ] @@ -12465,7 +12465,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -12509,7 +12509,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -12520,7 +12520,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -12680,7 +12680,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", "zvariant_utils", ] @@ -12693,6 +12693,6 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.109", + "syn 2.0.111", "winnow 0.7.13", ] diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index 12bc856c15..098f38dd37 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -56,7 +56,7 @@ "@csstools/normalize.css": "12.1.1", "@emotion/babel-plugin": "11.13.5", "@emotion/react": "11.14.0", - "@iconify/json": "2.2.410", + "@iconify/json": "2.2.411", "@monaco-editor/react": "4.7.0", "@tanstack/react-query": "5.90.7", "@tanstack/react-router": "1.134.15", diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 150cd41a03..4f885c00fb 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.16", - "mihomo_alpha": "alpha-66781a5", + "mihomo_alpha": "alpha-8b6ba22", "clash_rs": "v0.9.2", "clash_premium": "2023-09-05-gdcc8d87", "clash_rs_alpha": "0.9.2-alpha+sha.87c7b2c" @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-11-24T22:21:21.998Z" + "updated_at": "2025-11-26T22:21:25.971Z" } diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index 68c9bc4ec4..58e0fa8d73 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -346,8 +346,8 @@ importers: specifier: 11.14.0 version: 11.14.0(@types/react@19.2.2)(react@19.2.0) '@iconify/json': - specifier: 2.2.410 - version: 2.2.410 + specifier: 2.2.411 + version: 2.2.411 '@monaco-editor/react': specifier: 4.7.0 version: 4.7.0(monaco-editor@0.54.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -1821,8 +1821,8 @@ packages: prettier-plugin-ember-template-tag: optional: true - '@iconify/json@2.2.410': - resolution: {integrity: sha512-0IhW9Sfudf3cPQHoCwr2gJMMUUkLW01WIkGoP9PbwVKXl1I/KTRHtM9IchLufT8M86QHBWRcinApzkL60TH9vA==} + '@iconify/json@2.2.411': + resolution: {integrity: sha512-lbNY5utR46XT2seUTBNiqKwd0uxSq2lJfyg8WRxpThmlS1bk79eSToT9biraG1wzKKt0tCjJos9aZxj5Us9RTw==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -10341,7 +10341,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/json@2.2.410': + '@iconify/json@2.2.411': dependencies: '@iconify/types': 2.0.0 pathe: 2.0.3 diff --git a/filebrowser/frontend/pnpm-lock.yaml b/filebrowser/frontend/pnpm-lock.yaml index 5a68228916..362845b2f7 100644 --- a/filebrowser/frontend/pnpm-lock.yaml +++ b/filebrowser/frontend/pnpm-lock.yaml @@ -13,10 +13,10 @@ importers: version: 2.0.1(vue@3.5.25(typescript@5.9.3)) '@vueuse/core': specifier: ^14.0.0 - version: 14.0.0(vue@3.5.25(typescript@5.9.3)) + version: 14.1.0(vue@3.5.25(typescript@5.9.3)) '@vueuse/integrations': specifier: ^14.0.0 - version: 14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)) + version: 14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)) ace-builds: specifier: ^1.43.2 version: 1.43.4 @@ -79,7 +79,7 @@ importers: version: 3.5.25(typescript@5.9.3) vue-final-modal: specifier: ^4.5.5 - version: 4.5.5(@vueuse/core@14.0.0(vue@3.5.25(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.25(typescript@5.9.3)) + version: 4.5.5(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(@vueuse/integrations@14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.25(typescript@5.9.3)) vue-i18n: specifier: ^11.1.10 version: 11.2.2(vue@3.5.25(typescript@5.9.3)) @@ -1373,13 +1373,13 @@ packages: vue: optional: true - '@vueuse/core@14.0.0': - resolution: {integrity: sha512-d6tKRWkZE8IQElX2aHBxXOMD478fHIYV+Dzm2y9Ag122ICBpNKtGICiXKOhWU3L1kKdttDD9dCMS4bGP3jhCTQ==} + '@vueuse/core@14.1.0': + resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==} peerDependencies: vue: ^3.5.0 - '@vueuse/integrations@14.0.0': - resolution: {integrity: sha512-5A0X7q9qyLtM3xyghq5nK/NEESf7cpcZlkQgXTMuW4JWiAMYxc1ImdhhGrk4negFBsq3ejvAlRmLdNrkcTzk1Q==} + '@vueuse/integrations@14.1.0': + resolution: {integrity: sha512-eNQPdisnO9SvdydTIXnTE7c29yOsJBD/xkwEyQLdhDC/LKbqrFpXHb3uS//7NcIrQO3fWVuvMGp8dbK6mNEMCA==} peerDependencies: async-validator: ^4 axios: ^1 @@ -1420,11 +1420,11 @@ packages: universal-cookie: optional: true - '@vueuse/metadata@14.0.0': - resolution: {integrity: sha512-6yoGqbJcMldVCevkFiHDBTB1V5Hq+G/haPlGIuaFZHpXC0HADB0EN1ryQAAceiW+ryS3niUwvdFbGiqHqBrfVA==} + '@vueuse/metadata@14.1.0': + resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==} - '@vueuse/shared@14.0.0': - resolution: {integrity: sha512-mTCA0uczBgurRlwVaQHfG0Ja7UdGe4g9mwffiJmvLiTtp1G4AQyIjej6si/k8c8pUwTfVpNufck+23gXptPAkw==} + '@vueuse/shared@14.1.0': + resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==} peerDependencies: vue: ^3.5.0 @@ -3945,25 +3945,25 @@ snapshots: typescript: 5.9.3 vue: 3.5.25(typescript@5.9.3) - '@vueuse/core@14.0.0(vue@3.5.25(typescript@5.9.3))': + '@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3))': dependencies: '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 14.0.0 - '@vueuse/shared': 14.0.0(vue@3.5.25(typescript@5.9.3)) + '@vueuse/metadata': 14.1.0 + '@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3)) vue: 3.5.25(typescript@5.9.3) - '@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3))': + '@vueuse/integrations@14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3))': dependencies: - '@vueuse/core': 14.0.0(vue@3.5.25(typescript@5.9.3)) - '@vueuse/shared': 14.0.0(vue@3.5.25(typescript@5.9.3)) + '@vueuse/core': 14.1.0(vue@3.5.25(typescript@5.9.3)) + '@vueuse/shared': 14.1.0(vue@3.5.25(typescript@5.9.3)) vue: 3.5.25(typescript@5.9.3) optionalDependencies: focus-trap: 7.6.2 jwt-decode: 4.0.0 - '@vueuse/metadata@14.0.0': {} + '@vueuse/metadata@14.1.0': {} - '@vueuse/shared@14.0.0(vue@3.5.25(typescript@5.9.3))': + '@vueuse/shared@14.1.0(vue@3.5.25(typescript@5.9.3))': dependencies: vue: 3.5.25(typescript@5.9.3) @@ -5013,10 +5013,10 @@ snapshots: transitivePeerDependencies: - supports-color - vue-final-modal@4.5.5(@vueuse/core@14.0.0(vue@3.5.25(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.25(typescript@5.9.3)): + vue-final-modal@4.5.5(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(@vueuse/integrations@14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.25(typescript@5.9.3)): dependencies: - '@vueuse/core': 14.0.0(vue@3.5.25(typescript@5.9.3)) - '@vueuse/integrations': 14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)) + '@vueuse/core': 14.1.0(vue@3.5.25(typescript@5.9.3)) + '@vueuse/integrations': 14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)) focus-trap: 7.6.2 vue: 3.5.25(typescript@5.9.3) diff --git a/lede/target/linux/x86/64/config-6.12 b/lede/target/linux/x86/64/config-6.12 index 37fe21fe76..675fc4da29 100644 --- a/lede/target/linux/x86/64/config-6.12 +++ b/lede/target/linux/x86/64/config-6.12 @@ -477,6 +477,7 @@ CONFIG_SENSORS_K10TEMP=y CONFIG_SENSORS_K8TEMP=y # CONFIG_SENSORS_OXP is not set CONFIG_SENSORS_VIA_CPUTEMP=y +CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_8250_PNP=y # CONFIG_SERIAL_MULTI_INSTANTIATE is not set CONFIG_SLS=y diff --git a/mieru/Makefile b/mieru/Makefile index af0330b9ef..d530c4a312 100644 --- a/mieru/Makefile +++ b/mieru/Makefile @@ -32,7 +32,7 @@ PROJECT_NAME=$(shell basename "${ROOT}") # - pkg/version/current.go # # Use `tools/bump_version.sh` script to change all those files at one shot. -VERSION="3.23.0" +VERSION="3.24.0" # With .ONESHELL, each recipe is executed in a single shell instance. # This allows `cd` to affect subsequent commands in the same recipe. diff --git a/mieru/build/package/mieru/amd64/debian/DEBIAN/control b/mieru/build/package/mieru/amd64/debian/DEBIAN/control index f0f9760bbe..b56b7e9ee6 100755 --- a/mieru/build/package/mieru/amd64/debian/DEBIAN/control +++ b/mieru/build/package/mieru/amd64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mieru -Version: 3.23.0 +Version: 3.24.0 Section: net Priority: optional Architecture: amd64 diff --git a/mieru/build/package/mieru/amd64/rpm/mieru.spec b/mieru/build/package/mieru/amd64/rpm/mieru.spec index 28a3c3f5dd..07b49d919a 100644 --- a/mieru/build/package/mieru/amd64/rpm/mieru.spec +++ b/mieru/build/package/mieru/amd64/rpm/mieru.spec @@ -1,5 +1,5 @@ Name: mieru -Version: 3.23.0 +Version: 3.24.0 Release: 1%{?dist} Summary: Mieru proxy client License: GPLv3+ diff --git a/mieru/build/package/mieru/arm64/debian/DEBIAN/control b/mieru/build/package/mieru/arm64/debian/DEBIAN/control index a6d2fb10d6..91159d163a 100755 --- a/mieru/build/package/mieru/arm64/debian/DEBIAN/control +++ b/mieru/build/package/mieru/arm64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mieru -Version: 3.23.0 +Version: 3.24.0 Section: net Priority: optional Architecture: arm64 diff --git a/mieru/build/package/mieru/arm64/rpm/mieru.spec b/mieru/build/package/mieru/arm64/rpm/mieru.spec index 28a3c3f5dd..07b49d919a 100644 --- a/mieru/build/package/mieru/arm64/rpm/mieru.spec +++ b/mieru/build/package/mieru/arm64/rpm/mieru.spec @@ -1,5 +1,5 @@ Name: mieru -Version: 3.23.0 +Version: 3.24.0 Release: 1%{?dist} Summary: Mieru proxy client License: GPLv3+ diff --git a/mieru/build/package/mita/amd64/debian/DEBIAN/control b/mieru/build/package/mita/amd64/debian/DEBIAN/control index f6bc87d34f..4cf5b40d36 100755 --- a/mieru/build/package/mita/amd64/debian/DEBIAN/control +++ b/mieru/build/package/mita/amd64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mita -Version: 3.23.0 +Version: 3.24.0 Section: net Priority: optional Architecture: amd64 diff --git a/mieru/build/package/mita/amd64/rpm/mita.spec b/mieru/build/package/mita/amd64/rpm/mita.spec index fd8f4f960b..08a07200ea 100644 --- a/mieru/build/package/mita/amd64/rpm/mita.spec +++ b/mieru/build/package/mita/amd64/rpm/mita.spec @@ -1,5 +1,5 @@ Name: mita -Version: 3.23.0 +Version: 3.24.0 Release: 1%{?dist} Summary: Mieru proxy server License: GPLv3+ diff --git a/mieru/build/package/mita/arm64/debian/DEBIAN/control b/mieru/build/package/mita/arm64/debian/DEBIAN/control index 3de011dd1f..d10e8d9a0d 100755 --- a/mieru/build/package/mita/arm64/debian/DEBIAN/control +++ b/mieru/build/package/mita/arm64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mita -Version: 3.23.0 +Version: 3.24.0 Section: net Priority: optional Architecture: arm64 diff --git a/mieru/build/package/mita/arm64/rpm/mita.spec b/mieru/build/package/mita/arm64/rpm/mita.spec index ddcec1428b..e75f8df978 100644 --- a/mieru/build/package/mita/arm64/rpm/mita.spec +++ b/mieru/build/package/mita/arm64/rpm/mita.spec @@ -1,5 +1,5 @@ Name: mita -Version: 3.23.0 +Version: 3.24.0 Release: 1%{?dist} Summary: Mieru proxy server License: GPLv3+ diff --git a/mieru/docs/server-install.md b/mieru/docs/server-install.md index c274fb82bf..17bf958ea8 100644 --- a/mieru/docs/server-install.md +++ b/mieru/docs/server-install.md @@ -18,32 +18,32 @@ Or you can manually install and configure proxy server using the steps below. ```sh # Debian / Ubuntu - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita_3.23.0_amd64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita_3.24.0_amd64.deb # Debian / Ubuntu - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita_3.23.0_arm64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita_3.24.0_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita-3.23.0-1.x86_64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita-3.24.0-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita-3.23.0-1.aarch64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita-3.24.0-1.aarch64.rpm ``` ## Install mita package ```sh # Debian / Ubuntu - X86_64 -sudo dpkg -i mita_3.23.0_amd64.deb +sudo dpkg -i mita_3.24.0_amd64.deb # Debian / Ubuntu - ARM 64 -sudo dpkg -i mita_3.23.0_arm64.deb +sudo dpkg -i mita_3.24.0_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -sudo rpm -Uvh --force mita-3.23.0-1.x86_64.rpm +sudo rpm -Uvh --force mita-3.24.0-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -sudo rpm -Uvh --force mita-3.23.0-1.aarch64.rpm +sudo rpm -Uvh --force mita-3.24.0-1.aarch64.rpm ``` Those instructions can also be used to upgrade the version of mita software package. diff --git a/mieru/docs/server-install.zh_CN.md b/mieru/docs/server-install.zh_CN.md index 5311ecb6d0..affc48d240 100644 --- a/mieru/docs/server-install.zh_CN.md +++ b/mieru/docs/server-install.zh_CN.md @@ -18,32 +18,32 @@ sudo python3 setup.py --lang=zh ```sh # Debian / Ubuntu - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita_3.23.0_amd64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita_3.24.0_amd64.deb # Debian / Ubuntu - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita_3.23.0_arm64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita_3.24.0_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita-3.23.0-1.x86_64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita-3.24.0-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.23.0/mita-3.23.0-1.aarch64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.24.0/mita-3.24.0-1.aarch64.rpm ``` ## 安装 mita 软件包 ```sh # Debian / Ubuntu - X86_64 -sudo dpkg -i mita_3.23.0_amd64.deb +sudo dpkg -i mita_3.24.0_amd64.deb # Debian / Ubuntu - ARM 64 -sudo dpkg -i mita_3.23.0_arm64.deb +sudo dpkg -i mita_3.24.0_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -sudo rpm -Uvh --force mita-3.23.0-1.x86_64.rpm +sudo rpm -Uvh --force mita-3.24.0-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -sudo rpm -Uvh --force mita-3.23.0-1.aarch64.rpm +sudo rpm -Uvh --force mita-3.24.0-1.aarch64.rpm ``` 上述指令也可以用来升级 mita 软件包的版本。 diff --git a/mieru/pkg/common/ascii.go b/mieru/pkg/common/ascii.go index cdf6650726..ad91755169 100644 --- a/mieru/pkg/common/ascii.go +++ b/mieru/pkg/common/ascii.go @@ -26,7 +26,7 @@ const ( // Common64Set contains 64 selected common characters. // This value can change in different software releases. - Common64Set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-" + Common64Set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/" ) var ( diff --git a/mieru/pkg/protocol/mux.go b/mieru/pkg/protocol/mux.go index 31e87b92b7..96fe4ccb5f 100644 --- a/mieru/pkg/protocol/mux.go +++ b/mieru/pkg/protocol/mux.go @@ -510,7 +510,6 @@ func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayPropert underlay := &PacketUnderlay{ baseUnderlay: *newBaseUnderlay(false, properties.MTU()), conn: conn, - packetQueue: make(chan bufferWithAddr, packetChanCapacityServer), sessionCleanTicker: time.NewTicker(sessionCleanInterval), users: m.users, } diff --git a/mieru/pkg/protocol/session.go b/mieru/pkg/protocol/session.go index 3608eb385d..3052d944bf 100644 --- a/mieru/pkg/protocol/session.go +++ b/mieru/pkg/protocol/session.go @@ -127,13 +127,14 @@ type Session struct { recvQueue *segmentTree // segments waiting to be read by application recvChan chan *segment // channel to receive segments from underlay - nextSend uint32 // next sequence number to send a segment - nextRecv uint32 // next sequence number to receive - lastSend uint32 // last segment sequence number sent - lastRXTime time.Time // last timestamp when a segment is received - lastTXTime time.Time // last timestamp when a segment is sent - ackOnDataRecv atomic.Bool // whether ack should be sent due to receive of new data - unreadBuf []byte // payload removed from the recvQueue that haven't been read by application + nextSend uint32 // next sequence number to send a segment + nextRecv uint32 // next sequence number to receive + lastSend uint32 // last segment sequence number sent + lastRXTime time.Time // last timestamp when a segment is received + lastTXTime time.Time // last timestamp when a segment is sent + nextRetransmissionTime time.Time // time that need to retransmit a segment in sendBuf + ackOnDataRecv atomic.Bool // whether ack should be sent due to receive of new data + unreadBuf []byte // payload removed from the recvQueue that haven't been read by application uploadBytes metrics.Metric // number of bytes from client to server, only used by server downloadBytes metrics.Metric // number of bytes from server to client, only used by server @@ -687,66 +688,78 @@ func (s *Session) runOutputOncePacket() { hasLoss := false hasTimeout := false var bytesInFlight int64 - - // Resend segments in sendBuf. - // - // Iterate all the segments in sendBuf to calculate bytesInFlight, - // but only resend segments if needed. - // - // Retransmission is not limited by window. - // - // To avoid deadlock, session can't be closed inside Ascend(). - s.oLock.Lock() totalTransmissionCount := 0 - s.sendBuf.Ascend(func(iter *segment) bool { - bytesInFlight += int64(packetOverhead + len(iter.payload)) - if iter.txCount >= txCountLimit { - err := fmt.Errorf("too many retransmission of %v", iter) - log.Debugf("%v is unhealthy: %v", s, err) - if s.outputHasErr.CompareAndSwap(false, true) { - close(s.outputErr) - } - closeSessionReason = err - return false - } - satisfyEarlyRetransmission := iter.ackCount >= earlyRetransmission && iter.txCount <= earlyRetransmissionLimit - if satisfyEarlyRetransmission || time.Since(iter.txTime) > iter.txTimeout { - if satisfyEarlyRetransmission { - hasLoss = true - } else { - hasTimeout = true - } - iter.ackCount = 0 - iter.txCount++ - iter.txTime = time.Now() - iter.txTimeout = mathext.Min(s.rttStat.RTO()*time.Duration(math.Pow(txTimeoutBackOff, float64(iter.txCount))), maxBackOffDuration) - if isDataAckProtocol(iter.metadata.Protocol()) { - das, _ := toDataAckStruct(iter.metadata) - das.unAckSeq = s.nextRecv - } - if err := s.output(iter, s.RemoteAddr()); err != nil { - err = fmt.Errorf("output() failed: %w", err) - log.Debugf("%v %v", s, err) + + if time.Since(s.nextRetransmissionTime) >= 0 { + // Resend segments in sendBuf. + // + // Iterate all the segments in sendBuf to calculate bytesInFlight and + // update nextRetransmissionTime, but only resend segments if needed. + // + // Retransmission is not limited by window. + // + // To avoid deadlock, session can't be closed inside Ascend(). + s.oLock.Lock() + var nextTX int64 = math.MaxInt64 + s.sendBuf.Ascend(func(iter *segment) bool { + bytesInFlight += int64(packetOverhead + len(iter.payload)) + nextTX = mathext.Min(nextTX, iter.txTime.Add(iter.txTimeout).UnixMicro()) + + if iter.txCount >= txCountLimit { + err := fmt.Errorf("too many retransmission of %v", iter) + log.Debugf("%v is unhealthy: %v", s, err) if s.outputHasErr.CompareAndSwap(false, true) { close(s.outputErr) } closeSessionReason = err return false } - bytesInFlight += int64(packetOverhead + len(iter.payload)) - totalTransmissionCount++ + + satisfyEarlyRetransmission := iter.ackCount >= earlyRetransmission && iter.txCount <= earlyRetransmissionLimit + if satisfyEarlyRetransmission || time.Since(iter.txTime) > iter.txTimeout { + if satisfyEarlyRetransmission { + hasLoss = true + } else { + hasTimeout = true + } + iter.ackCount = 0 + iter.txCount++ + iter.txTime = time.Now() + iter.txTimeout = mathext.Min(s.rttStat.RTO()*time.Duration(math.Pow(txTimeoutBackOff, float64(iter.txCount))), maxBackOffDuration) + if isDataAckProtocol(iter.metadata.Protocol()) { + das, _ := toDataAckStruct(iter.metadata) + das.unAckSeq = s.nextRecv + } + if err := s.output(iter, s.RemoteAddr()); err != nil { + err = fmt.Errorf("output() failed: %w", err) + log.Debugf("%v %v", s, err) + if s.outputHasErr.CompareAndSwap(false, true) { + close(s.outputErr) + } + closeSessionReason = err + return false + } + bytesInFlight += int64(packetOverhead + len(iter.payload)) + totalTransmissionCount++ + return true + } return true + }) + if nextTX != math.MaxInt64 { + s.nextRetransmissionTime = time.UnixMicro(nextTX) + } else { + // Account for new segments to be sent below. + s.nextRetransmissionTime = time.Now().Add(10 * time.Millisecond) + } + s.oLock.Unlock() + if closeSessionReason != nil { + s.closeWithError(closeSessionReason) + } + if hasTimeout { + s.cubicSendAlgorithm.OnTimeout() + } else if hasLoss { + s.cubicSendAlgorithm.OnLoss() } - return true - }) - s.oLock.Unlock() - if closeSessionReason != nil { - s.closeWithError(closeSessionReason) - } - if hasTimeout { - s.cubicSendAlgorithm.OnTimeout() - } else if hasLoss { - s.cubicSendAlgorithm.OnLoss() } // Send new segments in sendQueue. diff --git a/mieru/pkg/protocol/underlay_base.go b/mieru/pkg/protocol/underlay_base.go index 5d13ff5856..af60355b9a 100644 --- a/mieru/pkg/protocol/underlay_base.go +++ b/mieru/pkg/protocol/underlay_base.go @@ -35,10 +35,6 @@ const ( sessionChanCapacity = 64 sessionCleanInterval = 5 * time.Second - - // Buffer received network packets before they are dropped by OS kernel. - packetChanCapacityClient = 1024 - packetChanCapacityServer = 1024 ) // baseUnderlay contains a partial implementation of underlay. diff --git a/mieru/pkg/protocol/underlay_packet.go b/mieru/pkg/protocol/underlay_packet.go index 2ec83425c6..c34f4d238f 100644 --- a/mieru/pkg/protocol/underlay_packet.go +++ b/mieru/pkg/protocol/underlay_packet.go @@ -49,9 +49,6 @@ type PacketUnderlay struct { baseUnderlay conn net.PacketConn - // packetQueue stores raw network packets payload not parsed to segments. - packetQueue chan bufferWithAddr - sessionCleanTicker *time.Ticker // ---- client fields ---- @@ -90,7 +87,6 @@ func NewPacketUnderlay(ctx context.Context, packetDialer apicommon.PacketDialer, u := &PacketUnderlay{ baseUnderlay: *newBaseUnderlay(true, mtu), conn: conn, - packetQueue: make(chan bufferWithAddr, packetChanCapacityClient), sessionCleanTicker: time.NewTicker(sessionCleanInterval), serverAddr: remoteAddr, block: block, @@ -172,28 +168,6 @@ func (u *PacketUnderlay) RunEventLoop(ctx context.Context) error { return stderror.ErrNullPointer } - // OS has limited buffer to store received UDP packets. - // Move the received UDP packets to user space as quickly as possible, - // so we can process them later at a slower pace. - go func() { - for { - select { - case <-ctx.Done(): - return - case <-u.done: - return - default: - } - if err := u.readOneSegment(); err != nil { - if stderror.IsTimeout(err) { - continue - } - log.Debugf("%v readOneSegment() failed: %v", u, err) - return - } - } - }() - for { select { case <-ctx.Done(): @@ -206,9 +180,9 @@ func (u *PacketUnderlay) RunEventLoop(ctx context.Context) error { u.cleanSessions() default: } - seg, addr, err := u.parseOneSegment() + seg, addr, err := u.readOneSegment() if err != nil { - return fmt.Errorf("parseOneSegment() failed: %w", err) + return fmt.Errorf("readOneSegment() failed: %w", err) } if log.IsLevelEnabled(log.TraceLevel) { log.Tracef("%v received %v from peer %v", u, seg, addr) @@ -317,29 +291,24 @@ func (u *PacketUnderlay) onCloseSession(seg *segment) error { return nil } -func (u *PacketUnderlay) readOneSegment() error { - var n int - var addr net.Addr - var err error +func (u *PacketUnderlay) readOneSegment() (*segment, net.Addr, error) { for { select { case <-u.done: - return io.ErrClosedPipe + return nil, nil, io.ErrClosedPipe default: } - common.SetReadTimeout(u.conn, readOneSegmentTimeout) - defer common.SetReadTimeout(u.conn, 0) - // Peer may select a different MTU. // Use the largest possible value here to avoid error. b := make([]byte, 1500) - n, addr, err = u.conn.ReadFrom(b) + common.SetReadTimeout(u.conn, readOneSegmentTimeout) + n, addr, err := u.conn.ReadFrom(b) if err != nil { if stderror.IsTimeout(err) { - return stderror.ErrTimeout + continue } - return fmt.Errorf("ReadFrom() failed: %w", err) + return nil, nil, fmt.Errorf("ReadFrom() failed: %w", err) } if u.isClient && addr.String() != u.serverAddr.String() { UnderlayUnsolicitedUDP.Add(1) @@ -362,167 +331,149 @@ func (u *PacketUnderlay) readOneSegment() error { } else { metrics.UploadBytes.Add(int64(n)) } - u.packetQueue <- bufferWithAddr{ - b: b, - addr: addr, + + // Read encrypted metadata. + encryptedMeta := b[:packetNonHeaderPosition] + isNewSessionReplay := false + if packetReplayCache.IsDuplicate(encryptedMeta[:cipher.DefaultOverhead], addr.String()) { + replay.NewSession.Add(1) + isNewSessionReplay = true } - return nil - } -} + nonce := encryptedMeta[:cipher.DefaultNonceSize] -func (u *PacketUnderlay) parseOneSegment() (*segment, net.Addr, error) { - var err error - for { - select { - case <-u.done: - return nil, nil, io.ErrClosedPipe - case raw := <-u.packetQueue: - b := raw.b - addr := raw.addr - - // Read encrypted metadata. - encryptedMeta := b[:packetNonHeaderPosition] - isNewSessionReplay := false - if packetReplayCache.IsDuplicate(encryptedMeta[:cipher.DefaultOverhead], addr.String()) { - replay.NewSession.Add(1) - isNewSessionReplay = true - } - nonce := encryptedMeta[:cipher.DefaultNonceSize] - - // Decrypt metadata. - var decryptedMeta []byte - var blockCipher cipher.BlockCipher - if u.isClient { - decryptedMeta, err = u.block.Decrypt(encryptedMeta) - cipher.ClientDirectDecrypt.Add(1) - if err != nil { - cipher.ClientFailedDirectDecrypt.Add(1) - if log.IsLevelEnabled(log.TraceLevel) { - log.Tracef("%v Decrypt() failed with packet from %v", u, addr) - } - continue + // Decrypt metadata. + var decryptedMeta []byte + var blockCipher cipher.BlockCipher + if u.isClient { + decryptedMeta, err = u.block.Decrypt(encryptedMeta) + cipher.ClientDirectDecrypt.Add(1) + if err != nil { + cipher.ClientFailedDirectDecrypt.Add(1) + if log.IsLevelEnabled(log.TraceLevel) { + log.Tracef("%v Decrypt() failed with packet from %v", u, addr) } - } else { - var decrypted bool - var err error - // Try existing sessions. - cipher.ServerIterateDecrypt.Add(1) - u.sessionMap.Range(func(k, v any) bool { - session := v.(*Session) - if session.block.Load() != nil && session.RemoteAddr().String() == addr.String() { - decryptedMeta, err = (*session.block.Load()).Decrypt(encryptedMeta) - if err == nil { - decrypted = true - blockCipher = *session.block.Load() - return false - } - } - return true - }) - if !decrypted { - // This is a new session. Try all registered users. - for _, user := range u.users { - var password []byte - password, err = hex.DecodeString(user.GetHashedPassword()) - if err != nil { - log.Debugf("Unable to decode hashed password %q from user %q", user.GetHashedPassword(), user.GetName()) - continue - } - if len(password) == 0 { - password = cipher.HashPassword([]byte(user.GetPassword()), []byte(user.GetName())) - } - blockCipher, decryptedMeta, err = cipher.TryDecrypt(encryptedMeta, password, true) - if err == nil { - decrypted = true - blockCipher.SetBlockContext(cipher.BlockContext{ - UserName: user.GetName(), - }) - break - } - } - } - if !decrypted { - cipher.ServerFailedIterateDecrypt.Add(1) - if isNewSessionReplay { - log.Debugf("found possible replay attack in %v from %v", u, addr) - } else if log.IsLevelEnabled(log.TraceLevel) { - log.Tracef("%v TryDecrypt() failed with packet from %v", u, addr) - } - continue - } else { - if blockCipher == nil { - panic("PacketUnderlay parseOneSegment(): block cipher is nil after decryption is successful") - } - if isNewSessionReplay { - replay.NewSessionDecrypted.Add(1) - log.Debugf("found possible replay attack with payload decrypted in %v from %v", u, addr) - continue - } - } - } - if len(decryptedMeta) != MetadataLength { - log.Debugf("decrypted metadata size %d is unexpected", len(decryptedMeta)) continue } - - // Read payload and construct segment. - var seg *segment - p := decryptedMeta[0] - if isSessionProtocol(protocolType(p)) { - ss := &sessionStruct{} - if err := ss.Unmarshal(decryptedMeta); err != nil { - if u.isClient { - return nil, nil, fmt.Errorf("Unmarshal() to sessionStruct failed: %w", err) - } else { - log.Debugf("%v Unmarshal() to sessionStruct failed: %v", u, err) - continue + } else { + var decrypted bool + var err error + // Try existing sessions. + cipher.ServerIterateDecrypt.Add(1) + u.sessionMap.Range(func(k, v any) bool { + session := v.(*Session) + if session.block.Load() != nil && session.RemoteAddr().String() == addr.String() { + decryptedMeta, err = (*session.block.Load()).Decrypt(encryptedMeta) + if err == nil { + decrypted = true + blockCipher = *session.block.Load() + return false } } - seg, err = u.parseSessionSegment(ss, nonce, b[packetNonHeaderPosition:], blockCipher) - if err != nil { - if u.isClient { - return nil, nil, err - } else { - log.Debugf("%v parseSessionSegment() failed: %v", u, err) + return true + }) + if !decrypted { + // This is a new session. Try all registered users. + for _, user := range u.users { + var password []byte + password, err = hex.DecodeString(user.GetHashedPassword()) + if err != nil { + log.Debugf("Unable to decode hashed password %q from user %q", user.GetHashedPassword(), user.GetName()) continue } - } - if blockCipher != nil { - seg.block = blockCipher - } - return seg, addr, nil - } else if isDataAckProtocol(protocolType(p)) { - das := &dataAckStruct{} - if err := das.Unmarshal(decryptedMeta); err != nil { - if u.isClient { - return nil, nil, fmt.Errorf("Unmarshal() to dataAckStruct failed: %w", err) - } else { - log.Debugf("%v Unmarshal() to dataAckStruct failed: %v", u, err) - continue + if len(password) == 0 { + password = cipher.HashPassword([]byte(user.GetPassword()), []byte(user.GetName())) + } + blockCipher, decryptedMeta, err = cipher.TryDecrypt(encryptedMeta, password, true) + if err == nil { + decrypted = true + blockCipher.SetBlockContext(cipher.BlockContext{ + UserName: user.GetName(), + }) + break } } - seg, err = u.parseDataAckSegment(das, nonce, b[packetNonHeaderPosition:], blockCipher) - if err != nil { - if u.isClient { - return nil, nil, err - } else { - log.Debugf("%v parseDataAckSegment() failed: %v", u, err) - continue - } + } + if !decrypted { + cipher.ServerFailedIterateDecrypt.Add(1) + if isNewSessionReplay { + log.Debugf("found possible replay attack in %v from %v", u, addr) + } else if log.IsLevelEnabled(log.TraceLevel) { + log.Tracef("%v TryDecrypt() failed with packet from %v", u, addr) } - if blockCipher != nil { - seg.block = blockCipher - } - return seg, addr, nil + continue } else { - if u.isClient { - return nil, nil, fmt.Errorf("unable to handle protocol %d", p) - } else { - log.Debugf("%v unable to handle protocol %d", u, p) + if blockCipher == nil { + panic("PacketUnderlay readOneSegment(): block cipher is nil after decryption is successful") + } + if isNewSessionReplay { + replay.NewSessionDecrypted.Add(1) + log.Debugf("found possible replay attack with payload decrypted in %v from %v", u, addr) continue } } } + if len(decryptedMeta) != MetadataLength { + log.Debugf("decrypted metadata size %d is unexpected", len(decryptedMeta)) + continue + } + + // Read payload and construct segment. + var seg *segment + p := decryptedMeta[0] + if isSessionProtocol(protocolType(p)) { + ss := &sessionStruct{} + if err := ss.Unmarshal(decryptedMeta); err != nil { + if u.isClient { + return nil, nil, fmt.Errorf("Unmarshal() to sessionStruct failed: %w", err) + } else { + log.Debugf("%v Unmarshal() to sessionStruct failed: %v", u, err) + continue + } + } + seg, err = u.parseSessionSegment(ss, nonce, b[packetNonHeaderPosition:], blockCipher) + if err != nil { + if u.isClient { + return nil, nil, err + } else { + log.Debugf("%v parseSessionSegment() failed: %v", u, err) + continue + } + } + if blockCipher != nil { + seg.block = blockCipher + } + return seg, addr, nil + } else if isDataAckProtocol(protocolType(p)) { + das := &dataAckStruct{} + if err := das.Unmarshal(decryptedMeta); err != nil { + if u.isClient { + return nil, nil, fmt.Errorf("Unmarshal() to dataAckStruct failed: %w", err) + } else { + log.Debugf("%v Unmarshal() to dataAckStruct failed: %v", u, err) + continue + } + } + seg, err = u.parseDataAckSegment(das, nonce, b[packetNonHeaderPosition:], blockCipher) + if err != nil { + if u.isClient { + return nil, nil, err + } else { + log.Debugf("%v parseDataAckSegment() failed: %v", u, err) + continue + } + } + if blockCipher != nil { + seg.block = blockCipher + } + return seg, addr, nil + } else { + if u.isClient { + return nil, nil, fmt.Errorf("unable to handle protocol %d", p) + } else { + log.Debugf("%v unable to handle protocol %d", u, p) + continue + } + } } } diff --git a/mieru/pkg/version/current.go b/mieru/pkg/version/current.go index 81b40a896b..856497348e 100644 --- a/mieru/pkg/version/current.go +++ b/mieru/pkg/version/current.go @@ -16,5 +16,5 @@ package version const ( - AppVersion = "3.23.0" + AppVersion = "3.24.0" ) diff --git a/mieru/test/deploy/packetdrop/libtest.sh b/mieru/test/deploy/packetdrop/libtest.sh index 3a84e7497c..8e76a04bd4 100755 --- a/mieru/test/deploy/packetdrop/libtest.sh +++ b/mieru/test/deploy/packetdrop/libtest.sh @@ -36,3 +36,17 @@ function print_mieru_client_thread_dump() { ./mieru get thread-dump echo "========== END OF MIERU CLIENT THREAD DUMP ==========" } + +function print_mieru_client_metrics() { + echo "========== BEGIN OF MIERU CLIENT METRICS ==========" + ./mieru get metrics + ./mieru get memory-statistics + echo "========== END OF MIERU CLIENT METRICS ==========" +} + +function print_mieru_server_metrics() { + echo "========== BEGIN OF MIERU SERVER METRICS ==========" + ./mita get metrics + ./mita get memory-statistics + echo "========== END OF MIERU SERVER METRICS ==========" +} diff --git a/mieru/test/deploy/packetdrop/test_tcp.sh b/mieru/test/deploy/packetdrop/test_tcp.sh index baf3426181..84fdce6b37 100755 --- a/mieru/test/deploy/packetdrop/test_tcp.sh +++ b/mieru/test/deploy/packetdrop/test_tcp.sh @@ -73,6 +73,14 @@ if [ "$?" -ne "0" ]; then exit 1 fi +# Print metrics and memory statistics. +./mita get users +sleep 1 +print_mieru_client_metrics +sleep 1 +print_mieru_server_metrics +sleep 1 + # Stop mieru client. ./mieru stop if [[ "$?" -ne 0 ]]; then diff --git a/mieru/test/deploy/packetdrop/test_udp.sh b/mieru/test/deploy/packetdrop/test_udp.sh index dd2d9828a3..ca43fd9137 100755 --- a/mieru/test/deploy/packetdrop/test_udp.sh +++ b/mieru/test/deploy/packetdrop/test_udp.sh @@ -73,6 +73,14 @@ if [ "$?" -ne "0" ]; then exit 1 fi +# Print metrics and memory statistics. +./mita get users +sleep 1 +print_mieru_client_metrics +sleep 1 +print_mieru_server_metrics +sleep 1 + # Stop mieru client. ./mieru stop if [[ "$?" -ne 0 ]]; then diff --git a/openwrt-packages/luci-app-amlogic/Makefile b/openwrt-packages/luci-app-amlogic/Makefile index fdddf652e3..fbec226cf7 100644 --- a/openwrt-packages/luci-app-amlogic/Makefile +++ b/openwrt-packages/luci-app-amlogic/Makefile @@ -16,7 +16,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-amlogic -PKG_VERSION:=3.1.278 +PKG_VERSION:=3.1.280 PKG_RELEASE:=1 PKG_LICENSE:=GPL-2.0 License diff --git a/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-install-amlogic b/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-install-amlogic index a3cd3fc9c7..dd48c23cad 100755 --- a/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-install-amlogic +++ b/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-install-amlogic @@ -523,16 +523,21 @@ while [ $i -le $max_try ]; do sync echo "Edit uEnv.txt ..." - cat >uEnv.txt </dev/null + sed -i -E \ + -e "s|/dtb/amlogic.*|/dtb/amlogic/${FDTFILE}|" \ + -e "s|UUID=[^ ]*|UUID=${ROOTFS1_UUID}|" \ + -e "s|rootflags=compress=zstd:[^ ]*|rootflags=compress=zstd:${ZSTD_LEVEL}|" \ + extlinux/extlinux.conf } rm -f s905_autoscript* aml_autoscript* diff --git a/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-update-rockchip b/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-update-rockchip index f2ba071df5..682c4463b6 100755 --- a/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-update-rockchip +++ b/openwrt-packages/luci-app-amlogic/root/usr/sbin/openwrt-update-rockchip @@ -258,6 +258,14 @@ case $MYDEVICE_NAME in fi SOC="watermelon-pi" ;; +"Rockchip RK3576 DshanPi A1 Board") + if [ -n "${CURRENT_FDTFILE}" ]; then + MYDTB_FDTFILE="${CURRENT_FDTFILE}" + else + MYDTB_FDTFILE="rk3576-100ask-dshanpi-a1.dtb" + fi + SOC="100ask-dshanpi-a1" + ;; "Radxa ROCK 5B" | "Radxa ROCK 5 Model B") if [ -n "${CURRENT_FDTFILE}" ]; then MYDTB_FDTFILE="${CURRENT_FDTFILE}" diff --git a/openwrt-passwall/luci-app-passwall/Makefile b/openwrt-passwall/luci-app-passwall/Makefile index bf0de6f304..fd6fb7202f 100644 --- a/openwrt-passwall/luci-app-passwall/Makefile +++ b/openwrt-passwall/luci-app-passwall/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall -PKG_VERSION:=25.11.15 +PKG_VERSION:=25.11.27 PKG_RELEASE:=1 PKG_PO_VERSION:=$(PKG_VERSION) diff --git a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua index 5de50fcca8..853f828938 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua @@ -618,8 +618,14 @@ o = s:option(TextValue, _n("xhttp_extra"), " ", translate("An XHttpObject in JSO o:depends({ [_n("use_xhttp_extra")] = true }) o.rows = 15 o.wrap = "off" +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "xhttp_extra") + if raw then + return api.base64Decode(raw) + end +end o.custom_write = function(self, section, value) - m:set(section, self.option:sub(1 + #option_prefix), value) + m:set(section, "xhttp_extra", api.base64Encode(value)) local success, data = pcall(jsonc.parse, value) if success and data then local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address) @@ -642,7 +648,7 @@ o.validate = function(self, value) return value end o.custom_remove = function(self, section, value) - m:del(section, self.option:sub(1 + #option_prefix)) + m:del(section, "xhttp_extra") m:del(section, "download_address") end diff --git a/openwrt-passwall/luci-app-passwall/luasrc/passwall/api.lua b/openwrt-passwall/luci-app-passwall/luasrc/passwall/api.lua index 2e06645edf..24641bc1b8 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/passwall/api.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/passwall/api.lua @@ -179,19 +179,15 @@ function exec_call(cmd) end function base64Decode(text) - local raw = text if not text then return '' end - text = text:gsub("%z", "") - text = text:gsub("%c", "") - text = text:gsub("_", "/") - text = text:gsub("-", "+") - local mod4 = #text % 4 - text = text .. string.sub('====', mod4 + 1) - local result = nixio.bin.b64decode(text) + local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+") + local mod4 = #encoded % 4 + encoded = encoded .. string.sub('====', mod4 + 1) + local result = nixio.bin.b64decode(encoded) if result then return result:gsub("%z", "") else - return raw + return text end end diff --git a/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua b/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua index 61f2df6b8a..385c04ffb9 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -223,7 +223,7 @@ function gen_outbound(flag, node, tag, proxy_table) host = node.xhttp_host, -- 如果包含 "extra" 节,取 "extra" 内的内容,否则直接赋值给 extra extra = node.xhttp_extra and (function() - local success, parsed = pcall(jsonc.parse, node.xhttp_extra) + local success, parsed = pcall(jsonc.parse, api.base64Decode(node.xhttp_extra)) if success then return parsed.extra or parsed else 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 73eebf4943..3fcd473d2d 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 @@ -52,7 +52,7 @@ local api = require "luci.passwall.api" function add_node() { var nodes_link = document.getElementById("nodes_link").value; var group = (document.querySelector('#addlink_group_custom input[type="hidden"]')?.value || "default"); - nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").trim(); + nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").replace(/\s+/g, '').replace(/<[^>]*>/g, '').trim(); if (nodes_link != "") { var s = nodes_link.split('://'); if (s.length > 1) { 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 5724adeab0..c8a27c2f58 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 @@ -39,9 +39,9 @@ table td, .table .td { } @media (prefers-color-scheme: dark) { - ._now_use_bg { - background: #4a90e2 !important; - } + ._now_use_bg { + background: #4a90e2 !important; + } } .td.cbi-section-actions { @@ -56,34 +56,35 @@ table td, .table .td { .node-wrapper .cbi-input-checkbox { flex-grow: 0 !important; + flex-shrink: 0; flex-basis: auto; } .cbi-tabmenu > li { - margin-right: 2px !important; + margin-right: 2px !important; } .cbi-tabmenu > li:last-child { - margin-right: 0 !important; + margin-right: 0 !important; } .node-wrapper .drag-handle { - cursor: grab !important; + cursor: grab !important; display: inline-flex; align-items: center; - justify-content: center; - font-size: 18px; - padding: 0 !important; - line-height: inherit; - user-select: none; - height: 32px !important; - width: 32px; - min-width: 32px; + justify-content: center; + font-size: 20px; + font-weight: 100; + padding: 0 !important; + line-height: inherit; + user-select: none; + color: #00000070; + align-self: stretch; } .sortable-chosen { - background-color: rgba(220, 235, 245, 0.4) !important; - opacity: 0.7; + background-color: rgba(220, 235, 245, 0.4) !important; + opacity: 0.7; } .sortable-ghost { @@ -92,8 +93,8 @@ table td, .table .td { } .dragging-row { - background-color: rgba(131, 191, 255, 0.7) !important; - box-shadow: 0 4px 6px rgba(0,0,0,0.1); + background-color: rgba(131, 191, 255, 0.7) !important; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); } @@ -653,7 +654,7 @@ table td, .table .td { /{{id}}'" alt="<%:Edit%>" title="<%:Edit%>"> - + diff --git a/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/subscribe.lua index 2ee28eb8ea..17fb55839a 100755 --- a/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/subscribe.lua +++ b/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/subscribe.lua @@ -1207,7 +1207,7 @@ local function processData(szType, content, add_mode, group) result.xhttp_path = params.path result.xhttp_mode = params.mode or "auto" result.use_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil - result.xhttp_extra = (params.extra and params.extra ~= "") and params.extra or nil + result.xhttp_extra = (params.extra and params.extra ~= "") and api.base64Encode(params.extra) or nil local success, Data = pcall(jsonParse, params.extra) if success and Data then local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) diff --git a/shadowsocks-rust/Cargo.lock b/shadowsocks-rust/Cargo.lock index aeec3c9f42..8bc76cea32 100644 --- a/shadowsocks-rust/Cargo.lock +++ b/shadowsocks-rust/Cargo.lock @@ -140,7 +140,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -151,7 +151,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -356,7 +356,7 @@ dependencies = [ "serde", "serde_bytes", "simdutf8", - "thiserror 2.0.17", + "thiserror", "time", "uuid", ] @@ -742,7 +742,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ - "thiserror 2.0.17", + "thiserror", ] [[package]] @@ -820,7 +820,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -927,7 +927,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -1290,7 +1290,7 @@ dependencies = [ "ring", "rustls", "serde", - "thiserror 2.0.17", + "thiserror", "tinyvec", "tokio", "tokio-rustls", @@ -1318,7 +1318,7 @@ dependencies = [ "rustls", "serde", "smallvec", - "thiserror 2.0.17", + "thiserror", "tokio", "tokio-rustls", "tracing", @@ -1345,12 +1345,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -1911,7 +1910,7 @@ dependencies = [ "serde-value", "serde_json", "serde_yaml", - "thiserror 2.0.17", + "thiserror", "thread-id", "typemap-ors", "unicode-segmentation", @@ -2107,7 +2106,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2476,7 +2475,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2 0.6.1", - "thiserror 2.0.17", + "thiserror", "tokio", "tracing", "web-time", @@ -2497,7 +2496,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror", "tinyvec", "tracing", "web-time", @@ -2593,7 +2592,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.17", + "thiserror", ] [[package]] @@ -2781,7 +2780,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3083,7 +3082,7 @@ dependencies = [ "shadowsocks-crypto", "socket2 0.6.1", "spin", - "thiserror 2.0.17", + "thiserror", "tokio", "tokio-tfo", "trait-variant", @@ -3150,7 +3149,7 @@ dependencies = [ "sysexits", "syslog-tracing", "tcmalloc", - "thiserror 2.0.17", + "thiserror", "time", "tokio", "tracing", @@ -3201,7 +3200,7 @@ dependencies = [ "smoltcp", "socket2 0.6.1", "spin", - "thiserror 2.0.17", + "thiserror", "tokio", "tokio-native-tls", "tokio-rustls", @@ -3488,7 +3487,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3501,33 +3500,13 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - [[package]] name = "thiserror" version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.17", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.110", + "thiserror-impl", ] [[package]] @@ -3755,12 +3734,12 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 1.0.69", + "thiserror", "time", "tracing-subscriber", ] @@ -3847,7 +3826,7 @@ dependencies = [ "libc", "log", "nix", - "thiserror 2.0.17", + "thiserror", "tokio", "tokio-util", "windows-sys 0.60.2", @@ -4136,7 +4115,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -4488,7 +4467,7 @@ dependencies = [ "futures", "libloading", "log", - "thiserror 2.0.17", + "thiserror", "windows-sys 0.60.2", "winreg 0.55.0", ] diff --git a/small/gn/Makefile b/small/gn/Makefile index c4c6849464..d5a53b14f2 100644 --- a/small/gn/Makefile +++ b/small/gn/Makefile @@ -11,7 +11,7 @@ PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gn.googlesource.com/gn.git PKG_SOURCE_DATE:=2025-11-23 PKG_SOURCE_VERSION:=a156d0b1306b09bf676a72e345ca978ef6093d95 -PKG_MIRROR_HASH:=04ae2d1ecc0dbdc43e0793aad17d0031858ff48cdfd4c07809eac0b45becf7c2 +PKG_MIRROR_HASH:=96b3463e6f983224f92ad56617727b003aad8b3da562c01a4db2d16ae97e406d PKG_LICENSE:=BSD 3-Clause PKG_LICENSE_FILES:=LICENSE diff --git a/small/luci-app-passwall/Makefile b/small/luci-app-passwall/Makefile index bf0de6f304..fd6fb7202f 100644 --- a/small/luci-app-passwall/Makefile +++ b/small/luci-app-passwall/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall -PKG_VERSION:=25.11.15 +PKG_VERSION:=25.11.27 PKG_RELEASE:=1 PKG_PO_VERSION:=$(PKG_VERSION) diff --git a/small/luci-app-passwall/htdocs/luci-static/resources/view/passwall/Sortable.min.js b/small/luci-app-passwall/htdocs/luci-static/resources/view/passwall/Sortable.min.js new file mode 100644 index 0000000000..95423a6491 --- /dev/null +++ b/small/luci-app-passwall/htdocs/luci-static/resources/view/passwall/Sortable.min.js @@ -0,0 +1,2 @@ +/*! Sortable 1.15.6 - MIT | git://github.com/SortableJS/Sortable.git */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(o){for(var t=1;tt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function g(t){return t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&f(t,e)||o&&t===n)return t}while(t!==n&&(t=g(t)))}return null}var m,v=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(v," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(v," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function b(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function D(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Ft(t){Z&&Z.parentNode[K]._isOutsideThisEl(t.target)}function jt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return kt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==jt.supportPointer&&"PointerEvent"in window&&(!u||c),emptyInsertThreshold:5};for(n in z.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Rt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&It,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),St.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,A())}function Ht(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Lt(t){t.draggable=!1}function Kt(){xt=!1}function Wt(t){return setTimeout(t,0)}function zt(t){return clearTimeout(t)}jt.prototype={constructor:jt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(vt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,Z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Ot.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Ot.push(o)}}(o),!Z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||et===l)){if(it=j(l),at=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return V({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),U("filter",n,{evt:e}),void(i&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return V({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),U("filter",n,{evt:e}),!0}))return void(i&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!Z&&n.parentNode===r&&(o=X(n),J=r,$=(Z=n).parentNode,tt=Z.nextSibling,et=n,st=a.group,ut={target:jt.dragged=Z,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ut.clientX-o.left,gt=ut.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,Z.style["will-change"]="all",o=function(){U("delayEnded",i,{evt:t}),jt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(Z.draggable=!0),i._triggerDragStart(t,e),V({sortable:i,name:"choose",originalEvent:t}),k(Z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){D(Z,t.trim(),Lt)}),h(l,"dragover",Bt),h(l,"mousemove",Bt),h(l,"touchmove",Bt),a.supportPointer?(h(l,"pointerup",i._onDrop),this.nativeDraggable||h(l,"pointercancel",i._onDrop)):(h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop)),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,Z.draggable=!0),U("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():jt.eventCanceled?this._onDrop():(a.supportPointer?(h(l,"pointerup",i._disableDelayedDrag),h(l,"pointercancel",i._disableDelayedDrag)):(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag)),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){Z&&Lt(Z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._disableDelayedDrag),p(t,"touchend",this._disableDelayedDrag),p(t,"touchcancel",this._disableDelayedDrag),p(t,"pointerup",this._disableDelayedDrag),p(t,"pointercancel",this._disableDelayedDrag),p(t,"mousemove",this._delayedDragTouchMoveHandler),p(t,"touchmove",this._delayedDragTouchMoveHandler),p(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(Z,"dragend",this),h(J,"dragstart",this._onDragStart));try{document.selection?Wt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;Dt=!1,J&&Z?(U("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Ft),n=this.options,t||k(Z,n.dragClass,!1),k(Z,n.ghostClass,!0),jt.active=this,t&&this._appendGhost(),V({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(dt){this._lastX=dt.clientX,this._lastY=dt.clientY,Xt();for(var t=document.elementFromPoint(dt.clientX,dt.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(dt.clientX,dt.clientY))!==e;)e=t;if(Z.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:dt.clientX,clientY:dt.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=g(t=e));Yt()}},_onTouchMove:function(t){if(ut){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=Q&&b(Q,!0),a=Q&&r&&r.a,l=Q&&r&&r.d,e=At&&wt&&E(wt),a=(i.clientX-ut.clientX+o.x)/(a||1)+(e?e[0]-Tt[0]:0)/(a||1),l=(i.clientY-ut.clientY+o.y)/(l||1)+(e?e[1]-Tt[1]:0)/(l||1);if(!jt.active&&!Dt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))E.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>E.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,Q),e?t.clientX<_.left-10||t.clientY" .. str or "" local num = 0 m.uci:foreach(appname, "nodes", function(s) - if s["group"] ~= "" and s["group"] == remark then + if s["group"] and s["group"]:lower() == remark:lower() then num = num + 1 end end) diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua index 5de50fcca8..853f828938 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua @@ -618,8 +618,14 @@ o = s:option(TextValue, _n("xhttp_extra"), " ", translate("An XHttpObject in JSO o:depends({ [_n("use_xhttp_extra")] = true }) o.rows = 15 o.wrap = "off" +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "xhttp_extra") + if raw then + return api.base64Decode(raw) + end +end o.custom_write = function(self, section, value) - m:set(section, self.option:sub(1 + #option_prefix), value) + m:set(section, "xhttp_extra", api.base64Encode(value)) local success, data = pcall(jsonc.parse, value) if success and data then local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address) @@ -642,7 +648,7 @@ o.validate = function(self, value) return value end o.custom_remove = function(self, section, value) - m:del(section, self.option:sub(1 + #option_prefix)) + m:del(section, "xhttp_extra") m:del(section, "download_address") end diff --git a/small/luci-app-passwall/luasrc/passwall/api.lua b/small/luci-app-passwall/luasrc/passwall/api.lua index 2e06645edf..24641bc1b8 100644 --- a/small/luci-app-passwall/luasrc/passwall/api.lua +++ b/small/luci-app-passwall/luasrc/passwall/api.lua @@ -179,19 +179,15 @@ function exec_call(cmd) end function base64Decode(text) - local raw = text if not text then return '' end - text = text:gsub("%z", "") - text = text:gsub("%c", "") - text = text:gsub("_", "/") - text = text:gsub("-", "+") - local mod4 = #text % 4 - text = text .. string.sub('====', mod4 + 1) - local result = nixio.bin.b64decode(text) + local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+") + local mod4 = #encoded % 4 + encoded = encoded .. string.sub('====', mod4 + 1) + local result = nixio.bin.b64decode(encoded) if result then return result:gsub("%z", "") else - return raw + return text end end diff --git a/small/luci-app-passwall/luasrc/passwall/util_xray.lua b/small/luci-app-passwall/luasrc/passwall/util_xray.lua index 61f2df6b8a..385c04ffb9 100644 --- a/small/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/small/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -223,7 +223,7 @@ function gen_outbound(flag, node, tag, proxy_table) host = node.xhttp_host, -- 如果包含 "extra" 节,取 "extra" 内的内容,否则直接赋值给 extra extra = node.xhttp_extra and (function() - local success, parsed = pcall(jsonc.parse, node.xhttp_extra) + local success, parsed = pcall(jsonc.parse, api.base64Decode(node.xhttp_extra)) if success then return parsed.extra or parsed else 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 73eebf4943..3fcd473d2d 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 @@ -52,7 +52,7 @@ local api = require "luci.passwall.api" function add_node() { var nodes_link = document.getElementById("nodes_link").value; var group = (document.querySelector('#addlink_group_custom input[type="hidden"]')?.value || "default"); - nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").trim(); + nodes_link = nodes_link.replace(/\t/g, "").replace(/\r\n|\r/g, "\n").replace(/\s+/g, '').replace(/<[^>]*>/g, '').trim(); if (nodes_link != "") { var s = nodes_link.split('://'); if (s.length > 1) { 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 f8f16e732e..c8a27c2f58 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 @@ -1,6 +1,7 @@ <% local api = require "luci.passwall.api" -%> + <% if api.is_js_luci() then -%> @@ -210,21 +239,6 @@ table td, .table .td { document.getElementById("set_node_name").innerHTML = ""; } - function row_swap(btn, up) { - const row = btn.closest("tr"); - if (!row) return; - const parent = row.parentNode; - if (up) { - const prev = row.previousElementSibling; - if (prev && !prev.classList.contains("cbi-section-table-titles")) { - parent.insertBefore(row, prev); - } - } else { - const next = row.nextElementSibling; - if (next) parent.insertBefore(next, row); - } - } - function row_top(btn) { const row = btn.closest("tr"); if (!row) return; @@ -548,6 +562,60 @@ table td, .table .td { } } } + + //列表拖动重排 + function initSortableForTable(table) { + if (!table) return null; + var root = table.querySelector('tbody') || table; + if (root._sortable_initialized) return root._sortable_instance; + root._sortable_initialized = true; + var opts = { + handle: ".drag-handle", + draggable: "tr.cbi-section-table-row", + animation: 150, + ghostClass: "dragging-row", + fallbackOnBody: true, + forceFallback: false, + swapThreshold: 0.65, + onEnd: function (evt) { + //var group = evt.to.id.replace("cbi-passwall-nodes-", "").replace("-table", ""); + //save_current_page_order(group); // 自动提交保存 + } + }; + try { + var instance = Sortable.create(root, opts); + root._sortable_instance = instance; + return instance; + } catch (err) { + root._sortable_initialized = false; + console.error("Sortable init failed:", err); + return null; + } + } + + function initAllSortable(group_nodes) { + if (typeof Sortable === 'undefined') { + var retries = 0; + var maxRetries = 25; + var t = setInterval(function () { + retries++; + if (typeof Sortable !== 'undefined') { + clearInterval(t); + for (var group in group_nodes) { + var table = document.getElementById("cbi-passwall-nodes-" + group + "-table"); + initSortableForTable(table); + } + } else if (retries >= maxRetries) { + clearInterval(t); + } + }, 200); + } else { + for (var group in group_nodes) { + var table = document.getElementById("cbi-passwall-nodes-" + group + "-table"); + initSortableForTable(table); + } + } + }