update 2024-02-27 00:21:27

This commit is contained in:
github-actions[bot] 2024-02-27 00:21:27 +08:00
parent 8441053fce
commit 0eed6b20da
32 changed files with 435 additions and 316 deletions

View File

@ -1,4 +1,4 @@
# Copyright (C) 2020-2023 Hyy2001X <https://github.com/Hyy2001X> # Copyright (C) 2020-2024 Hyy2001X <https://github.com/Hyy2001X>
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
@ -16,7 +16,7 @@ define Package/$(PKG_NAME)
endef endef
define Package/$(PKG_NAME)/description define Package/$(PKG_NAME)/description
autoupdate - Upgrade OpenWrt by one-key autoupdate - One-key AutoUpdate
endef endef
define Build/Compile define Build/Compile

View File

@ -3,7 +3,7 @@
# AutoUpdate for Openwrt # AutoUpdate for Openwrt
# Dependences: wget-ssl/wget/uclient-fetch curl jq expr sysupgrade # Dependences: wget-ssl/wget/uclient-fetch curl jq expr sysupgrade
Version=V6.9.7 Version=V6.9.8
function TITLE() { function TITLE() {
clear && echo "Openwrt-AutoUpdate Script by Hyy2001 ${Version}" clear && echo "Openwrt-AutoUpdate Script by Hyy2001 ${Version}"
@ -22,6 +22,9 @@ function SHELL_HELP() {
-f 跳过版本号校验,并强制刷写固件 ${Red}(危险)${White} * -f 跳过版本号校验,并强制刷写固件 ${Red}(危险)${White} *
-F, --force-flash 强制刷写固件 ${Red}(危险)${White} * -F, --force-flash 强制刷写固件 ${Red}(危险)${White} *
-P, --proxy 优先开启镜像加速下载固件 * -P, --proxy 优先开启镜像加速下载固件 *
${Next} A 自动选择
${Next} F Cloudflare Workers
${Next} G Ghproxy
-D <Downloader> 使用指定的下载器 <wget-ssl | wget | curl | uclient-fetch> * -D <Downloader> 使用指定的下载器 <wget-ssl | wget | curl | uclient-fetch> *
--decompress 解压 img.gz 固件后再更新固件 * --decompress 解压 img.gz 固件后再更新固件 *
--skip-verify 跳过固件 SHA256 校验 ${Red}(危险)${White} * --skip-verify 跳过固件 SHA256 校验 ${Red}(危险)${White} *
@ -653,15 +656,22 @@ function UPGRADE() {
;; ;;
-P | --proxy) -P | --proxy)
case $2 in case $2 in
A | F | G) A)
Proxy_Type=$2 Proxy_Type="All"
Special_Commands="${Special_Commands} [镜像加速 Automatic]"
shift shift
;; ;;
*) F)
Proxy_Type="All" Proxy_Type=$2
Special_Commands="${Special_Commands} [CF Workers]"
shift
;;
G)
Proxy_Type=$2
Special_Commands="${Special_Commands} [Ghproxy]"
shift
;; ;;
esac esac
Special_Commands="${Special_Commands} [镜像加速 ${Proxy_Type}]"
;; ;;
-D) -D)
DL_DEPENDS=($2) DL_DEPENDS=($2)
@ -785,14 +795,14 @@ $(echo -e "云端固件版本: ${CLOUD_FW_Version}${CHECKED_Type}")
esac esac
local URL local URL
case "${Proxy_Type}" in case "${Proxy_Type}" in
A | F | G) F | G)
URL="$(Proxy_X ${CLOUD_FW_Url} ${Proxy_Type}@@5)" URL="$(Proxy_X ${CLOUD_FW_Url} ${Proxy_Type}@@5)"
;; ;;
All) All)
URL="$(Proxy_X ${CLOUD_FW_Url} G@@2 F@@1 A@@1 X@@1)" URL="$(Proxy_X ${CLOUD_FW_Url} G@@2 F@@2 X@@1)"
;; ;;
*) *)
URL="$(Proxy_X ${CLOUD_FW_Url} X@@3 G@@1 F@@1 A@@1)" URL="$(Proxy_X ${CLOUD_FW_Url} X@@3 G@@1 F@@1)"
;; ;;
esac esac
DOWNLOADER --file-name ${CLOUD_FW_Name} --no-url-name --dl ${DL_DEPENDS[@]} --url ${URL} --path ${Firmware_Path} --timeout 15 --type 固件 DOWNLOADER --file-name ${CLOUD_FW_Name} --no-url-name --dl ${DL_DEPENDS[@]} --url ${URL} --path ${Firmware_Path} --timeout 15 --type 固件
@ -1102,17 +1112,14 @@ function Proxy_X() {
case "${Type}" in case "${Type}" in
raw) raw)
A=https://raw.fgit.cf/$(echo ${URL##*com/})
F=https://git.hyy2001.workers.dev/$(echo ${URL##*com/}) F=https://git.hyy2001.workers.dev/$(echo ${URL##*com/})
G=https://mirror.ghproxy.com/${URL} G=https://mirror.ghproxy.com/${URL}
;; ;;
release) release)
A=https://hub.fgit.cf/$(echo ${URL##*com/})
F=https://git.hyy2001.workers.dev/$(echo ${URL##*com/}) F=https://git.hyy2001.workers.dev/$(echo ${URL##*com/})
G=https://mirror.ghproxy.com/${URL} G=https://mirror.ghproxy.com/${URL}
;; ;;
codeload) codeload)
A=https://hub.fgit.cf/$(echo ${URL##*com/})
F=https://git.hyy2001.workers.dev/$(echo ${URL##*com/}) F=https://git.hyy2001.workers.dev/$(echo ${URL##*com/})
G=https://mirror.ghproxy.com/${URL} G=https://mirror.ghproxy.com/${URL}
;; ;;
@ -1120,9 +1127,6 @@ function Proxy_X() {
while [[ $1 ]];do while [[ $1 ]];do
local URL_Cache=$1 URL_Final local URL_Cache=$1 URL_Final
case $1 in case $1 in
A@@*)
URL_Final="${URL_Cache/A/${A}}"
;;
F@@*) F@@*)
URL_Final="${URL_Cache/F/${F}}" URL_Final="${URL_Cache/F/${F}}"
;; ;;

View File

@ -1,7 +1,3 @@
# SPDX-License-Identifier: GPL-3.0-only
#
# Copyright (C) 2022 ImmortalWrt.org
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=btop PKG_NAME:=btop
@ -37,11 +33,11 @@ define Package/btop/description
C++ version and continuation of bashtop and bpytop. C++ version and continuation of bashtop and bpytop.
endef endef
PROG_LDFLAGS:=-pthread -DFMT_HEADER_ONLY -D_FILE_OFFSET_BITS=64 BTOP_LDFLAGS:=-pthread -DFMT_HEADER_ONLY -D_FILE_OFFSET_BITS=64
MAKE_FLAGS+= \ MAKE_FLAGS+= \
PLATFORM=Linux \ PLATFORM=Linux \
OPTFLAGS="$(TARGET_CXXFLAGS)" \ OPTFLAGS="$(TARGET_CXXFLAGS)" \
LDCXXFLAGS="$(TARGET_LDFLAGS) $(PROG_LDFLAGS)" LDCXXFLAGS="$(TARGET_LDFLAGS) $(BTOP_LDFLAGS)"
define Package/btop/install define Package/btop/install
$(INSTALL_DIR) $(1)/usr/bin $(INSTALL_DIR) $(1)/usr/bin

View File

@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-autoupdate PKG_NAME:=luci-app-autoupdate
PKG_VERSION:=9 PKG_VERSION:=9
PKG_RELEASE:=2 PKG_RELEASE:=3
LUCI_TITLE:=LuCI Support for autoupdate LUCI_TITLE:=LuCI Support for autoupdate
LUCI_DEPENDS:=+autoupdate LUCI_DEPENDS:=+autoupdate

View File

@ -16,7 +16,7 @@ enable = s:option(Flag, "enable", translate("Enable"), translate("Automatically
enable.default = 0 enable.default = 0
enable.optional = false enable.optional = false
proxy = s:option(Flag, "proxy", translate("Preference Mirror Speedup"), translate("Preference Mirror for speeding up downloads while upgrading (For Mainland)")) proxy = s:option(Flag, "proxy", translate("Preference Mirror Speedup"), translate("Preference Mirror for speeding up download"))
proxy.default = 1 proxy.default = 1
proxy:depends("enable", "1") proxy:depends("enable", "1")
proxy.optional = false proxy.optional = false
@ -24,8 +24,8 @@ proxy.optional = false
proxy_type = s:option(ListValue, "proxy_type", translate("Mirror Station")) proxy_type = s:option(ListValue, "proxy_type", translate("Mirror Station"))
proxy_type.default = "A" proxy_type.default = "A"
proxy_type:value("A", translate("Automatic selection (Recommend)")) proxy_type:value("A", translate("Automatic selection (Recommend)"))
proxy_type:value("G", translate("GitHub Proxy - Ghproxy (Maybe faster)")) proxy_type:value("G", translate("GitHub Proxy"))
proxy_type:value("F", translate("FastGit UK")) proxy_type:value("F", translate("CF Workers"))
proxy_type:depends("proxy", "1") proxy_type:depends("proxy", "1")
proxy_type.optional = false proxy_type.optional = false

View File

@ -25,14 +25,14 @@ msgstr "镜像站"
msgid "Automatic selection (Recommend)" msgid "Automatic selection (Recommend)"
msgstr "自动选择 (推荐)" msgstr "自动选择 (推荐)"
msgid "GitHub Proxy - Ghproxy (Maybe faster)" msgid "GitHub Proxy"
msgstr "GitHub Proxy - Ghproxy (也许更快)" msgstr "GitHub Proxy - Ghproxy"
msgid "FastGit UK" msgid "CF Workers"
msgstr "FastGit UK" msgstr "Cloudflare Workers"
msgid "Preference Mirror for speeding up downloads while upgrading (For Mainland)" msgid "Preference Mirror for speeding up download"
msgstr "定时更新固件时优先启用镜像加速 (适用与被墙地区)" msgstr "优先使用镜像站加速下载"
msgid "Advanced Settings" msgid "Advanced Settings"
msgstr "高级设置" msgstr "高级设置"
@ -53,7 +53,7 @@ msgid "Upgrade without keeping config"
msgstr "不保留配置" msgstr "不保留配置"
msgid "Please don't select it unless you know what you're doing!" msgid "Please don't select it unless you know what you're doing!"
msgstr "请勿随意勾选除非你知道自己在做什么!" msgstr "请勿随意勾选,除非你知道自己在做什么!"
msgid "Recommend to set the AUTOUPDATE time to an uncommon time" msgid "Recommend to set the AUTOUPDATE time to an uncommon time"
msgstr "建议设置定时更新时间为设备不常用的时间" msgstr "建议设置定时更新时间为设备不常用的时间"

View File

@ -25,14 +25,14 @@ msgstr "镜像站"
msgid "Automatic selection (Recommend)" msgid "Automatic selection (Recommend)"
msgstr "自动选择 (推荐)" msgstr "自动选择 (推荐)"
msgid "GitHub Proxy - Ghproxy (Maybe faster)" msgid "GitHub Proxy"
msgstr "GitHub Proxy - Ghproxy (也许更快)" msgstr "GitHub Proxy - Ghproxy"
msgid "FastGit UK" msgid "CF Workers"
msgstr "FastGit UK" msgstr "Cloudflare Workers"
msgid "Preference Mirror for speeding up downloads while upgrading (For Mainland)" msgid "Preference Mirror for speeding up download"
msgstr "定时更新固件时优先启用镜像加速 (适用与被墙地区)" msgstr "优先使用镜像站加速下载"
msgid "Advanced Settings" msgid "Advanced Settings"
msgstr "高级设置" msgstr "高级设置"
@ -53,7 +53,7 @@ msgid "Upgrade without keeping config"
msgstr "不保留配置" msgstr "不保留配置"
msgid "Please don't select it unless you know what you're doing!" msgid "Please don't select it unless you know what you're doing!"
msgstr "请勿随意勾选除非你知道自己在做什么!" msgstr "请勿随意勾选,除非你知道自己在做什么!"
msgid "Recommend to set the AUTOUPDATE time to an uncommon time" msgid "Recommend to set the AUTOUPDATE time to an uncommon time"
msgstr "建议设置定时更新时间为设备不常用的时间" msgstr "建议设置定时更新时间为设备不常用的时间"
@ -70,6 +70,9 @@ msgstr "用于检测固件版本更新以及下载固件的地址"
msgid "Firmware Flag" msgid "Firmware Flag"
msgstr "固件标签" msgstr "固件标签"
msgid "Log Path"
msgstr "日志路径"
msgid "Do Upgrade" msgid "Do Upgrade"
msgstr "执行更新" msgstr "执行更新"

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-mosdns PKG_NAME:=luci-app-mosdns
PKG_VERSION:=1.5.17 PKG_VERSION:=1.5.18
PKG_RELEASE:=1 PKG_RELEASE:=1
LUCI_TITLE:=LuCI Support for mosdns LUCI_TITLE:=LuCI Support for mosdns

View File

@ -174,8 +174,7 @@ o.default = "geosite.dat"
o:value("geosite.dat", "v2ray-geosite") o:value("geosite.dat", "v2ray-geosite")
o:value("https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt", "anti-AD") o:value("https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt", "anti-AD")
o:value("https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt", "Cats-Team/AdRules") o:value("https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt", "Cats-Team/AdRules")
o:value("https://raw.githubusercontent.com/ookangzheng/dbl-oisd-nl/master/dbl_light.txt", "oisd (small)") o:value("https://raw.githubusercontent.com/neodevpro/neodevhost/master/domain", "NEO DEV HOST")
o:value("https://raw.githubusercontent.com/ookangzheng/dbl-oisd-nl/master/dbl.txt", "oisd (big)")
o = s:taboption("basic", Button, "_reload", translate("Restart-Service"), translate("Restart the MosDNS process to take effect of new configuration")) o = s:taboption("basic", Button, "_reload", translate("Restart-Service"), translate("Restart the MosDNS process to take effect of new configuration"))
o.write = function() o.write = function()

View File

@ -228,7 +228,9 @@ start_service() {
if [ -f "/etc/mosdns/rule/.ad_source" ]; then if [ -f "/etc/mosdns/rule/.ad_source" ]; then
for url in $ad_source; for url in $ad_source;
do do
[ "$url" = "geosite.dat" ] && continue if [ "$url" = "geosite.dat" ] || [ $(echo "$url" | grep -c -E "^file://") -eq 1 ]; then
continue
fi
if [ $(grep -c "$url" "/etc/mosdns/rule/.ad_source") -eq 0 ]; then if [ $(grep -c "$url" "/etc/mosdns/rule/.ad_source") -eq 0 ]; then
update_list=1 update_list=1
break break

View File

@ -54,10 +54,17 @@ get_adlist() (
adlist_update() { adlist_update() {
[ "$(uci -q get mosdns.config.adblock)" != 1 ] && exit 0 [ "$(uci -q get mosdns.config.adblock)" != 1 ] && exit 0
lock_file=/var/lock/mosdns_ad_update.lock
ad_source=$(uci -q get mosdns.config.ad_source) ad_source=$(uci -q get mosdns.config.ad_source)
AD_TMPDIR=$(mktemp -d) || exit 1 AD_TMPDIR=$(mktemp -d) || exit 1
mirror="" mirror=""
: > /etc/mosdns/rule/.ad_source : > /etc/mosdns/rule/.ad_source
if [ -f "$lock_file" ]; then
has_update=0
exit 0
else
: > $lock_file
fi
has_update=0 has_update=0
for url in $ad_source; for url in $ad_source;
do do
@ -83,7 +90,7 @@ adlist_update() {
\cp $AD_TMPDIR/* /etc/mosdns/rule/adlist \cp $AD_TMPDIR/* /etc/mosdns/rule/adlist
} }
fi fi
rm -rf "$AD_TMPDIR" rm -rf "$AD_TMPDIR" $lock_file
} }
geodat_update() ( geodat_update() (

View File

@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=4.74-4 PKG_VERSION:=4.75-1
PKG_RELEASE:= PKG_RELEASE:=
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \

View File

@ -54,7 +54,8 @@ for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then if e.node_type == "normal" then
nodes_table[#nodes_table + 1] = { nodes_table[#nodes_table + 1] = {
id = e[".name"], id = e[".name"],
remarks = e["remark"] remarks = e["remark"],
type = e["type"]
} }
end end
if e.protocol == "_balancing" then if e.protocol == "_balancing" then
@ -80,11 +81,13 @@ local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balan
o:depends({ [option_name("protocol")] = "_balancing" }) o:depends({ [option_name("protocol")] = "_balancing" })
o:value("random") o:value("random")
o:value("leastPing") o:value("leastPing")
o.default = "random" o:value("leastLoad")
o.default = "leastLoad"
-- 探测地址 -- 探测地址
local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL.")) local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
o:depends({ [option_name("balancingStrategy")] = "leastPing" }) o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o:depends({ [option_name("balancingStrategy")] = "leastLoad" })
local o = s:option(Value, option_name("probeUrl"), translate("Probe URL")) local o = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
o:depends({ [option_name("useCustomProbeUrl")] = true }) o:depends({ [option_name("useCustomProbeUrl")] = true })
@ -94,6 +97,7 @@ o.description = translate("The URL used to detect the connection status.")
-- 探测间隔 -- 探测间隔
local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval")) local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
o:depends({ [option_name("balancingStrategy")] = "leastPing" }) o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o:depends({ [option_name("balancingStrategy")] = "leastLoad" })
o.default = "1m" o.default = "1m"
o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.") o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
@ -522,4 +526,21 @@ o.default = 0
o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay") o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay")
o.default = 0 o.default = 0
o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy."))
o.default = ""
o:value("", translate("Close(Not use)"))
for k, v in pairs(nodes_table) do
if v.type == "Xray" then
o:value(v.id, v.remarks)
end
end
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then
s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("to_node")]:depends({ [option_name("protocol")] = v })
end
end
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -65,13 +65,13 @@ o.default = "eth1"
o:depends({ [option_name("protocol")] = "_iface" }) o:depends({ [option_name("protocol")] = "_iface" })
local nodes_table = {} local nodes_table = {}
local balancers_table = {}
local iface_table = {} local iface_table = {}
for k, e in ipairs(api.get_valid_nodes()) do for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then if e.node_type == "normal" then
nodes_table[#nodes_table + 1] = { nodes_table[#nodes_table + 1] = {
id = e[".name"], id = e[".name"],
remarks = e["remark"] remarks = e["remark"],
type = e["type"]
} }
end end
if e.protocol == "_iface" then if e.protocol == "_iface" then
@ -89,9 +89,6 @@ if #nodes_table > 0 then
o = s:option(Value, option_name("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not.")) o = s:option(Value, option_name("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true }) o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
for k, v in pairs(balancers_table) do
o:value(v.id, v.remarks)
end
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remarks) o:value(v.id, v.remarks)
end end
@ -110,9 +107,6 @@ uci:foreach(appname, "shunt_rules", function(e)
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [option_name("protocol")] = "_shunt" })
if #nodes_table > 0 then if #nodes_table > 0 then
for k, v in pairs(balancers_table) do
o:value(v.id, v.remarks)
end
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remarks) o:value(v.id, v.remarks)
end end
@ -142,9 +136,6 @@ o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole")) o:value("_blackhole", translate("Blackhole"))
if #nodes_table > 0 then if #nodes_table > 0 then
for k, v in pairs(balancers_table) do
o:value(v.id, v.remarks)
end
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remarks) o:value(v.id, v.remarks)
end end
@ -631,4 +622,18 @@ o:value("prefer_ipv6")
o:value("ipv4_only") o:value("ipv4_only")
o:value("ipv6_only") o:value("ipv6_only")
o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy."))
o.default = ""
o:value("", translate("Close(Not use)"))
for k, v in pairs(nodes_table) do
if v.type == "sing-box" then
o:value(v.id, v.remarks)
end
end
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then
o:depends({ [option_name("protocol")] = v })
end
end
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -875,6 +875,53 @@ function gen_config(var)
table.insert(inbounds, inbound) table.insert(inbounds, inbound)
end end
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end
local default_outTag = outbound.tag
if node.shadowtls == "1" then
local _node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = node.shadowtls_version,
password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil,
address = node.address,
port = node.port,
tls = "1",
tls_serverName = node.shadowtls_serverName,
utls = node.shadowtls_utls,
fingerprint = node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls")
if shadowtls_outbound then
table.insert(outbounds_table, shadowtls_outbound)
outbound.detour = outbound.tag .. "_shadowtls"
outbound.server = nil
outbound.server_port = nil
end
end
if node.to_node then
local to_node = uci:get_all(appname, node.to_node)
if to_node then
local to_outbound = gen_outbound(nil, to_node)
if to_outbound then
if shunt_rule_name then
to_outbound.tag = outbound.tag
outbound.tag = node[".name"]
else
to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag
end
to_outbound.detour = outbound.tag
table.insert(outbounds_table, to_outbound)
default_outTag = to_outbound.tag
end
end
end
return default_outTag
end
if node.protocol == "_shunt" then if node.protocol == "_shunt" then
local rules = {} local rules = {}
@ -903,34 +950,14 @@ function gen_config(var)
elseif preproxy_node and api.is_normal_node(preproxy_node) then elseif preproxy_node and api.is_normal_node(preproxy_node) then
local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag) local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag)
if preproxy_outbound then if preproxy_outbound then
if preproxy_node.shadowtls == "1" then set_outbound_detour(preproxy_node, preproxy_outbound, outbounds, preproxy_tag)
local _node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = preproxy_node.shadowtls_version,
password = (preproxy_node.shadowtls_version == "2" or preproxy_node.shadowtls_version == "3") and preproxy_node.shadowtls_password or nil,
address = preproxy_node.address,
port = preproxy_node.port,
tls = "1",
tls_serverName = preproxy_node.shadowtls_serverName,
utls = preproxy_node.shadowtls_utls,
fingerprint = preproxy_node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(flag, _node, preproxy_tag .. "_shadowtls")
if shadowtls_outbound then
table.insert(outbounds, shadowtls_outbound)
preproxy_outbound.detour = preproxy_outbound.tag .. "_shadowtls"
preproxy_outbound.server = nil
preproxy_outbound.server_port = nil
end
end
table.insert(outbounds, preproxy_outbound) table.insert(outbounds, preproxy_outbound)
else else
preproxy_enabled = false preproxy_enabled = false
end end
end end
local function gen_shunt_node(rule_name, _node_id, as_proxy) local function gen_shunt_node(rule_name, _node_id)
if not rule_name then return nil, nil end if not rule_name then return nil, nil end
if not _node_id then _node_id = node[rule_name] or "nil" end if not _node_id then _node_id = node[rule_name] or "nil" end
local rule_outboundTag local rule_outboundTag
@ -1002,27 +1029,7 @@ function gen_config(var)
end end
local _outbound = gen_outbound(flag, _node, rule_name, { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil }) local _outbound = gen_outbound(flag, _node, rule_name, { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil })
if _outbound then if _outbound then
if _node.shadowtls == "1" then set_outbound_detour(_node, _outbound, outbounds, rule_name)
local shadowtls_node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = _node.shadowtls_version,
password = (_node.shadowtls_version == "2" or _node.shadowtls_version == "3") and _node.shadowtls_password or nil,
address = _node.address,
port = _node.port,
tls = "1",
tls_serverName = _node.shadowtls_serverName,
utls = _node.shadowtls_utls,
fingerprint = _node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(flag, shadowtls_node, rule_name .. "_shadowtls", { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil })
if shadowtls_outbound then
table.insert(outbounds, shadowtls_outbound)
_outbound.detour = _outbound.tag .. "_shadowtls"
_outbound.server = nil
_outbound.server_port = nil
end
end
table.insert(outbounds, _outbound) table.insert(outbounds, _outbound)
rule_outboundTag = rule_name rule_outboundTag = rule_name
end end
@ -1201,46 +1208,23 @@ function gen_config(var)
for index, value in ipairs(rules) do for index, value in ipairs(rules) do
table.insert(route.rules, rules[index]) table.insert(route.rules, rules[index])
end end
else elseif node.protocol == "_iface" then
local outbound = nil if node.iface then
if node.protocol == "_iface" then local outbound = {
if node.iface then type = "direct",
outbound = { tag = node_id,
type = "direct", bind_interface = node.iface,
tag = node_id, routing_mark = 255,
bind_interface = node.iface, }
routing_mark = 255, table.insert(outbounds, outbound)
}
sys.call("touch /tmp/etc/passwall/iface/" .. node.iface)
end
else
outbound = gen_outbound(flag, node)
if outbound then
if node.shadowtls == "1" then
local shadowtls_node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = node.shadowtls_version,
password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil,
address = node.address,
port = node.port,
tls = "1",
tls_serverName = node.shadowtls_serverName,
utls = node.shadowtls_utls,
fingerprint = node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(flag, shadowtls_node, outbound.tag .. "_shadowtls")
if shadowtls_outbound then
table.insert(outbounds, shadowtls_outbound)
outbound.detour = outbound.tag .. "_shadowtls"
outbound.server = nil
outbound.server_port = nil
end
end
end
end
if outbound then
default_outTag = outbound.tag default_outTag = outbound.tag
route.final = default_outTag
sys.call("touch /tmp/etc/passwall/iface/" .. node.iface)
end
else
local outbound = gen_outbound(flag, node)
if outbound then
default_outTag = set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
route.final = default_outTag route.final = default_outTag
end end

View File

@ -248,6 +248,11 @@ function gen_outbound(flag, node, tag, proxy_table)
reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil
} }
} }
if node.protocol == "wireguard" then
result.settings.kernelMode = false
end
local alpn = {} local alpn = {}
if node.alpn and node.alpn ~= "default" then if node.alpn and node.alpn ~= "default" then
string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) string.gsub(node.alpn, '[^' .. "," .. ']+', function(w)
@ -665,7 +670,7 @@ function gen_config(var)
selector = valid_nodes, selector = valid_nodes,
strategy = { type = _node.balancingStrategy or "random" } strategy = { type = _node.balancingStrategy or "random" }
} }
if _node.balancingStrategy == "leastPing" then if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" then
if not observatory then if not observatory then
observatory = { observatory = {
subjectSelector = { "blc-" }, subjectSelector = { "blc-" },
@ -692,6 +697,34 @@ function gen_config(var)
return balancer, rule return balancer, rule
end end
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end
local default_outTag = outbound.tag
if node.to_node then
local to_node = uci:get_all(appname, node.to_node)
if to_node then
local to_outbound = gen_outbound(nil, to_node)
if to_outbound then
if shunt_rule_name then
to_outbound.tag = outbound.tag
outbound.tag = node[".name"]
else
to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag
end
to_outbound.proxySettings = {
tag = outbound.tag,
transportLayer = true
}
table.insert(outbounds_table, to_outbound)
default_outTag = to_outbound.tag
end
end
end
return default_outTag
end
if node.protocol == "_shunt" then if node.protocol == "_shunt" then
local rules = {} local rules = {}
local balancers = {} local balancers = {}
@ -723,6 +756,7 @@ function gen_config(var)
elseif preproxy_node and api.is_normal_node(preproxy_node) then elseif preproxy_node and api.is_normal_node(preproxy_node) then
local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag, { fragment = xray_settings.fragment == "1" or nil }) local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag, { fragment = xray_settings.fragment == "1" or nil })
if preproxy_outbound then if preproxy_outbound then
set_outbound_detour(preproxy_node, preproxy_outbound, outbounds, preproxy_tag)
table.insert(outbounds, preproxy_outbound) table.insert(outbounds, preproxy_outbound)
else else
preproxy_enabled = false preproxy_enabled = false
@ -738,7 +772,7 @@ function gen_config(var)
end end
end end
local function gen_shunt_node(rule_name, _node_id, as_proxy) local function gen_shunt_node(rule_name, _node_id)
if not rule_name then return nil, nil end if not rule_name then return nil, nil end
if not _node_id then _node_id = node[rule_name] or "nil" end if not _node_id then _node_id = node[rule_name] or "nil" end
local rule_outboundTag local rule_outboundTag
@ -832,6 +866,7 @@ function gen_config(var)
end end
local _outbound = gen_outbound(flag, _node, rule_name, proxy_table) local _outbound = gen_outbound(flag, _node, rule_name, proxy_table)
if _outbound then if _outbound then
set_outbound_detour(_node, _outbound, outbounds, rule_name)
table.insert(outbounds, _outbound) table.insert(outbounds, _outbound)
if proxy then preproxy_used = true end if proxy then preproxy_used = true end
rule_outboundTag = rule_name rule_outboundTag = rule_name
@ -984,26 +1019,27 @@ function gen_config(var)
} }
} }
end end
else elseif node.protocol == "_iface" then
local outbound = nil if node.iface then
if node.protocol == "_iface" then local outbound = {
if node.iface then protocol = "freedom",
outbound = { tag = "outbound",
protocol = "freedom", streamSettings = {
tag = "outbound", sockopt = {
streamSettings = { mark = 255,
sockopt = { interface = node.iface
mark = 255,
interface = node.iface
}
} }
} }
sys.call("touch /tmp/etc/passwall/iface/" .. node.iface) }
end table.insert(outbounds, outbound)
else sys.call("touch /tmp/etc/passwall/iface/" .. node.iface)
outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil }) end
else
local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil })
if outbound then
set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound)
end end
if outbound then table.insert(outbounds, outbound) end
routing = { routing = {
domainStrategy = "AsIs", domainStrategy = "AsIs",
domainMatcher = "hybrid", domainMatcher = "hybrid",

View File

@ -1569,3 +1569,9 @@ msgstr "分片间隔ms"
msgid "If is domain name, The requested domain name will be resolved to IP before connect." msgid "If is domain name, The requested domain name will be resolved to IP before connect."
msgstr "如果是域名,域名将在请求发出之前解析为 IP。" msgstr "如果是域名,域名将在请求发出之前解析为 IP。"
msgid "Landing node"
msgstr "落地节点"
msgid "Only support a layer of proxy."
msgstr "仅支持一层代理。"

View File

@ -7,6 +7,8 @@
8.8.8.8 8.8.8.8
208.67.222.222 208.67.222.222
208.67.220.220 208.67.220.220
104.16.249.249
104.16.248.249
1.1.1.1 1.1.1.1
1.1.1.2 1.1.1.2
1.0.0.1 1.0.0.1
@ -16,4 +18,4 @@
2001:b28:f23c::/48 2001:b28:f23c::/48
2001:b28:f23d::/48 2001:b28:f23d::/48
2001:b28:f23f::/48 2001:b28:f23f::/48
2001:b28:f242::/48 2001:b28:f242::/48

View File

@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2 PKG_NAME:=luci-app-passwall2
PKG_VERSION:=1.26-3 PKG_VERSION:=1.27-1
PKG_RELEASE:= PKG_RELEASE:=
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \

View File

@ -54,7 +54,8 @@ for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then if e.node_type == "normal" then
nodes_table[#nodes_table + 1] = { nodes_table[#nodes_table + 1] = {
id = e[".name"], id = e[".name"],
remarks = e["remark"] remarks = e["remark"],
type = e["type"]
} }
end end
if e.protocol == "_balancing" then if e.protocol == "_balancing" then
@ -80,11 +81,13 @@ local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balan
o:depends({ [option_name("protocol")] = "_balancing" }) o:depends({ [option_name("protocol")] = "_balancing" })
o:value("random") o:value("random")
o:value("leastPing") o:value("leastPing")
o.default = "random" o:value("leastLoad")
o.default = "leastLoad"
-- 探测地址 -- 探测地址
local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL.")) local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
o:depends({ [option_name("balancingStrategy")] = "leastPing" }) o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o:depends({ [option_name("balancingStrategy")] = "leastLoad" })
local o = s:option(Value, option_name("probeUrl"), translate("Probe URL")) local o = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
o:depends({ [option_name("useCustomProbeUrl")] = true }) o:depends({ [option_name("useCustomProbeUrl")] = true })
@ -94,6 +97,7 @@ o.description = translate("The URL used to detect the connection status.")
-- 探测间隔 -- 探测间隔
local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval")) local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
o:depends({ [option_name("balancingStrategy")] = "leastPing" }) o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o:depends({ [option_name("balancingStrategy")] = "leastLoad" })
o.default = "1m" o.default = "1m"
o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.") o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
@ -523,4 +527,21 @@ o.default = 0
o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay") o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay")
o.default = 0 o.default = 0
o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy."))
o.default = ""
o:value("", translate("Close(Not use)"))
for k, v in pairs(nodes_table) do
if v.type == "Xray" then
o:value(v.id, v.remarks)
end
end
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then
s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("to_node")]:depends({ [option_name("protocol")] = v })
end
end
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -65,13 +65,13 @@ o.default = "eth1"
o:depends({ [option_name("protocol")] = "_iface" }) o:depends({ [option_name("protocol")] = "_iface" })
local nodes_table = {} local nodes_table = {}
local balancers_table = {}
local iface_table = {} local iface_table = {}
for k, e in ipairs(api.get_valid_nodes()) do for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then if e.node_type == "normal" then
nodes_table[#nodes_table + 1] = { nodes_table[#nodes_table + 1] = {
id = e[".name"], id = e[".name"],
remarks = e["remark"] remarks = e["remark"],
type = e["type"]
} }
end end
if e.protocol == "_iface" then if e.protocol == "_iface" then
@ -89,9 +89,6 @@ if #nodes_table > 0 then
o = s:option(Value, option_name("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not.")) o = s:option(Value, option_name("main_node"), string.format('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true }) o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
for k, v in pairs(balancers_table) do
o:value(v.id, v.remarks)
end
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remarks) o:value(v.id, v.remarks)
end end
@ -110,9 +107,6 @@ uci:foreach(appname, "shunt_rules", function(e)
o:depends({ [option_name("protocol")] = "_shunt" }) o:depends({ [option_name("protocol")] = "_shunt" })
if #nodes_table > 0 then if #nodes_table > 0 then
for k, v in pairs(balancers_table) do
o:value(v.id, v.remarks)
end
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remarks) o:value(v.id, v.remarks)
end end
@ -142,9 +136,6 @@ o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole")) o:value("_blackhole", translate("Blackhole"))
if #nodes_table > 0 then if #nodes_table > 0 then
for k, v in pairs(balancers_table) do
o:value(v.id, v.remarks)
end
for k, v in pairs(iface_table) do for k, v in pairs(iface_table) do
o:value(v.id, v.remarks) o:value(v.id, v.remarks)
end end
@ -631,4 +622,18 @@ o:value("prefer_ipv6")
o:value("ipv4_only") o:value("ipv4_only")
o:value("ipv6_only") o:value("ipv6_only")
o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy."))
o.default = ""
o:value("", translate("Close(Not use)"))
for k, v in pairs(nodes_table) do
if v.type == "sing-box" then
o:value(v.id, v.remarks)
end
end
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then
o:depends({ [option_name("protocol")] = v })
end
end
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -872,6 +872,54 @@ function gen_config(var)
node.address = server_host node.address = server_host
node.port = server_port node.port = server_port
end end
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end
local default_outTag = outbound.tag
if node.shadowtls == "1" then
local _node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = node.shadowtls_version,
password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil,
address = node.address,
port = node.port,
tls = "1",
tls_serverName = node.shadowtls_serverName,
utls = node.shadowtls_utls,
fingerprint = node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls")
if shadowtls_outbound then
table.insert(outbounds_table, shadowtls_outbound)
outbound.detour = outbound.tag .. "_shadowtls"
outbound.server = nil
outbound.server_port = nil
end
end
if node.to_node then
local to_node = uci:get_all(appname, node.to_node)
if to_node then
local to_outbound = gen_outbound(nil, to_node)
if to_outbound then
if shunt_rule_name then
to_outbound.tag = outbound.tag
outbound.tag = node[".name"]
else
to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag
end
to_outbound.detour = outbound.tag
table.insert(outbounds_table, to_outbound)
default_outTag = to_outbound.tag
end
end
end
return default_outTag
end
if node.protocol == "_shunt" then if node.protocol == "_shunt" then
local rules = {} local rules = {}
@ -900,34 +948,14 @@ function gen_config(var)
elseif preproxy_node and api.is_normal_node(preproxy_node) then elseif preproxy_node and api.is_normal_node(preproxy_node) then
local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag) local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag)
if preproxy_outbound then if preproxy_outbound then
if preproxy_node.shadowtls == "1" then set_outbound_detour(preproxy_node, preproxy_outbound, outbounds, preproxy_tag)
local _node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = preproxy_node.shadowtls_version,
password = (preproxy_node.shadowtls_version == "2" or preproxy_node.shadowtls_version == "3") and preproxy_node.shadowtls_password or nil,
address = preproxy_node.address,
port = preproxy_node.port,
tls = "1",
tls_serverName = preproxy_node.shadowtls_serverName,
utls = preproxy_node.shadowtls_utls,
fingerprint = preproxy_node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(flag, _node, preproxy_tag .. "_shadowtls")
if shadowtls_outbound then
table.insert(outbounds, shadowtls_outbound)
preproxy_outbound.detour = preproxy_outbound.tag .. "_shadowtls"
preproxy_outbound.server = nil
preproxy_outbound.server_port = nil
end
end
table.insert(outbounds, preproxy_outbound) table.insert(outbounds, preproxy_outbound)
else else
preproxy_enabled = false preproxy_enabled = false
end end
end end
local function gen_shunt_node(rule_name, _node_id, as_proxy) local function gen_shunt_node(rule_name, _node_id)
if not rule_name then return nil, nil end if not rule_name then return nil, nil end
if not _node_id then _node_id = node[rule_name] or "nil" end if not _node_id then _node_id = node[rule_name] or "nil" end
local rule_outboundTag local rule_outboundTag
@ -999,27 +1027,7 @@ function gen_config(var)
end end
local _outbound = gen_outbound(flag, _node, rule_name, { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil }) local _outbound = gen_outbound(flag, _node, rule_name, { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil })
if _outbound then if _outbound then
if _node.shadowtls == "1" then set_outbound_detour(_node, _outbound, outbounds, rule_name)
local shadowtls_node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = _node.shadowtls_version,
password = (_node.shadowtls_version == "2" or _node.shadowtls_version == "3") and _node.shadowtls_password or nil,
address = _node.address,
port = _node.port,
tls = "1",
tls_serverName = _node.shadowtls_serverName,
utls = _node.shadowtls_utls,
fingerprint = _node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(flag, shadowtls_node, rule_name .. "_shadowtls", { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil })
if shadowtls_outbound then
table.insert(outbounds, shadowtls_outbound)
_outbound.detour = _outbound.tag .. "_shadowtls"
_outbound.server = nil
_outbound.server_port = nil
end
end
table.insert(outbounds, _outbound) table.insert(outbounds, _outbound)
rule_outboundTag = rule_name rule_outboundTag = rule_name
end end
@ -1196,46 +1204,23 @@ function gen_config(var)
for index, value in ipairs(rules) do for index, value in ipairs(rules) do
table.insert(route.rules, rules[index]) table.insert(route.rules, rules[index])
end end
else elseif node.protocol == "_iface" then
local outbound = nil if node.iface then
if node.protocol == "_iface" then local outbound = {
if node.iface then type = "direct",
outbound = { tag = node_id,
type = "direct", bind_interface = node.iface,
tag = node_id, routing_mark = 255,
bind_interface = node.iface, }
routing_mark = 255, table.insert(outbounds, outbound)
}
sys.call("touch /tmp/etc/passwall2/iface/" .. node.iface)
end
else
outbound = gen_outbound(flag, node)
if outbound then
if node.shadowtls == "1" then
local shadowtls_node = {
type = "sing-box",
protocol = "shadowtls",
shadowtls_version = node.shadowtls_version,
password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil,
address = node.address,
port = node.port,
tls = "1",
tls_serverName = node.shadowtls_serverName,
utls = node.shadowtls_utls,
fingerprint = node.shadowtls_fingerprint
}
local shadowtls_outbound = gen_outbound(flag, shadowtls_node, outbound.tag .. "_shadowtls")
if shadowtls_outbound then
table.insert(outbounds, shadowtls_outbound)
outbound.detour = outbound.tag .. "_shadowtls"
outbound.server = nil
outbound.server_port = nil
end
end
end
end
if outbound then
default_outTag = outbound.tag default_outTag = outbound.tag
route.final = default_outTag
sys.call("touch /tmp/etc/passwall2/iface/" .. node.iface)
end
else
local outbound = gen_outbound(flag, node)
if outbound then
default_outTag = set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
route.final = default_outTag route.final = default_outTag
end end

View File

@ -245,6 +245,11 @@ function gen_outbound(flag, node, tag, proxy_table)
reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil
} }
} }
if node.protocol == "wireguard" then
result.settings.kernelMode = false
end
local alpn = {} local alpn = {}
if node.alpn and node.alpn ~= "default" then if node.alpn and node.alpn ~= "default" then
string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) string.gsub(node.alpn, '[^' .. "," .. ']+', function(w)
@ -658,7 +663,7 @@ function gen_config(var)
selector = valid_nodes, selector = valid_nodes,
strategy = { type = _node.balancingStrategy or "random" } strategy = { type = _node.balancingStrategy or "random" }
} }
if _node.balancingStrategy == "leastPing" then if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" then
if not observatory then if not observatory then
observatory = { observatory = {
subjectSelector = { "blc-" }, subjectSelector = { "blc-" },
@ -685,6 +690,34 @@ function gen_config(var)
return balancer, rule return balancer, rule
end end
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end
local default_outTag = outbound.tag
if node.to_node then
local to_node = uci:get_all(appname, node.to_node)
if to_node then
local to_outbound = gen_outbound(nil, to_node)
if to_outbound then
if shunt_rule_name then
to_outbound.tag = outbound.tag
outbound.tag = node[".name"]
else
to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag
end
to_outbound.proxySettings = {
tag = outbound.tag,
transportLayer = true
}
table.insert(outbounds_table, to_outbound)
default_outTag = to_outbound.tag
end
end
end
return default_outTag
end
for k, v in pairs(nodes) do for k, v in pairs(nodes) do
if server_host and server_port then if server_host and server_port then
v.address = server_host v.address = server_host
@ -722,6 +755,7 @@ function gen_config(var)
elseif preproxy_node and api.is_normal_node(preproxy_node) then elseif preproxy_node and api.is_normal_node(preproxy_node) then
local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag, { fragment = xray_settings.fragment == "1" or nil }) local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag, { fragment = xray_settings.fragment == "1" or nil })
if preproxy_outbound then if preproxy_outbound then
set_outbound_detour(preproxy_node, preproxy_outbound, outbounds, preproxy_tag)
table.insert(outbounds, preproxy_outbound) table.insert(outbounds, preproxy_outbound)
else else
preproxy_enabled = false preproxy_enabled = false
@ -737,7 +771,7 @@ function gen_config(var)
end end
end end
local function gen_shunt_node(rule_name, _node_id, as_proxy) local function gen_shunt_node(rule_name, _node_id)
if not rule_name then return nil, nil end if not rule_name then return nil, nil end
if not _node_id then _node_id = node[rule_name] or "nil" end if not _node_id then _node_id = node[rule_name] or "nil" end
local rule_outboundTag local rule_outboundTag
@ -831,6 +865,7 @@ function gen_config(var)
end end
local _outbound = gen_outbound(flag, _node, rule_name, proxy_table) local _outbound = gen_outbound(flag, _node, rule_name, proxy_table)
if _outbound then if _outbound then
set_outbound_detour(_node, _outbound, outbounds, rule_name)
table.insert(outbounds, _outbound) table.insert(outbounds, _outbound)
if proxy then preproxy_used = true end if proxy then preproxy_used = true end
rule_outboundTag = rule_name rule_outboundTag = rule_name
@ -991,39 +1026,39 @@ function gen_config(var)
} }
} }
end end
else elseif node.protocol == "_iface" then
local outbound = nil if node.iface then
if node.protocol == "_iface" then local outbound = {
if node.iface then protocol = "freedom",
outbound = { tag = "outbound",
protocol = "freedom", streamSettings = {
tag = "outbound", sockopt = {
streamSettings = { mark = 255,
sockopt = { interface = node.iface
mark = 255,
interface = node.iface
}
} }
} }
sys.call("touch /tmp/etc/passwall2/iface/" .. node.iface) }
end table.insert(outbounds, outbound)
else sys.call("touch /tmp/etc/passwall2/iface/" .. node.iface)
outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil }) end
else
local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil })
if outbound then
local default_outTag = set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound)
routing = {
domainStrategy = "AsIs",
domainMatcher = "hybrid",
rules = {}
}
table.insert(routing.rules, {
_flag = "default",
type = "field",
outboundTag = default_outTag,
network = "tcp,udp"
})
end end
if outbound then table.insert(outbounds, outbound) end
routing = {
domainStrategy = "AsIs",
domainMatcher = "hybrid",
rules = {}
}
table.insert(routing.rules, {
_flag = "default",
type = "field",
outboundTag = node_id,
network = "tcp,udp"
})
end end
end end
if remote_dns_udp_server then if remote_dns_udp_server then

View File

@ -1482,3 +1482,9 @@ msgstr "分片间隔ms"
msgid "If is domain name, The requested domain name will be resolved to IP before connect." msgid "If is domain name, The requested domain name will be resolved to IP before connect."
msgstr "如果是域名,域名将在请求发出之前解析为 IP。" msgstr "如果是域名,域名将在请求发出之前解析为 IP。"
msgid "Landing node"
msgstr "落地节点"
msgid "Only support a layer of proxy."
msgstr "仅支持一层代理。"

View File

@ -13,9 +13,9 @@
if (s) if (s)
{ {
if (rv.ret=="0") if (rv.ret=="0")
s.innerHTML ="<font color='green'>"+"<%:Connect OK%>"+"</font>"; s.innerHTML ="<font style=\'color:green\'>"+"<%:Connect OK%>"+"</font>";
else else
s.innerHTML ="<font color='red'>"+"<%:Connect Error%>"+"</font>"; s.innerHTML ="<font style=\'color:red\'>"+"<%:Connect Error%>"+"</font>";
} }
btn.disabled = false; btn.disabled = false;
btn.value = '<%:Check Connect%>'; btn.value = '<%:Check Connect%>';

View File

@ -15,13 +15,13 @@
switch (rv.ret) switch (rv.ret)
{ {
case 0: case 0:
s.innerHTML ="<font color='green'>"+"<%:Refresh OK!%> "+"<%:Total Records:%>"+rv.retcount+"</font>"; s.innerHTML ="<font style=\'color:green\'>"+"<%:Refresh OK!%> "+"<%:Total Records:%>"+rv.retcount+"</font>";
break; break;
case 1: case 1:
s.innerHTML ="<font color='green'>"+"<%:No new data!%> "+"</font>"; s.innerHTML ="<font style=\'color:green\'>"+"<%:No new data!%> "+"</font>";
break; break;
default: default:
s.innerHTML ="<font color='red'>"+"<%:Refresh Error!%> "+"</font>"; s.innerHTML ="<font style=\'color:red\'>"+"<%:Refresh Error!%> "+"</font>";
break; break;
} }
} }

View File

@ -7,7 +7,7 @@
return false; return false;
} }
if (reset != "reset") { if (reset != "reset") {
s.innerHTML = "<font color='red'><%:The content entered is incorrect!%></font>"; s.innerHTML = "<font style=\'color:red\'><%:The content entered is incorrect!%></font>";
return false; return false;
} }
btn.disabled = true; btn.disabled = true;
@ -15,7 +15,7 @@
murl=dataname; murl=dataname;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "shadowsocksr","reset")%>', { set:murl }, function(x,rv) { XHR.get('<%=luci.dispatcher.build_url("admin", "services", "shadowsocksr","reset")%>', { set:murl }, function(x,rv) {
btn.value = '<%:Reset complete%>'; btn.value = '<%:Reset complete%>';
s.innerHTML = "<font color='green'><%:Reset complete%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Reset complete%></font>";
}); });
return false; return false;
} }

View File

@ -18,7 +18,7 @@
const wsPath = wsPaths[index]; const wsPath = wsPaths[index];
const tls = tlss[index]; const tls = tlss[index];
if (!dom) res() if (!dom) res()
port.innerHTML = '<font color="#0072c3">connect</font>'; port.innerHTML = '<font style=\"color:#0072c3\">connect</font>';
XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', { XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', {
index, index,
domain: dom.getAttribute("hint"), domain: dom.getAttribute("hint"),
@ -34,11 +34,11 @@
if (result.ping < 200) col = '#ff7700'; if (result.ping < 200) col = '#ff7700';
if (result.ping < 100) col = '#249400'; if (result.ping < 100) col = '#249400';
} }
dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>` dom.innerHTML = `<font style=\"color:${col}\">${(result.ping ? result.ping : "--") + " ms"}</font>`
if (result.socket) { if (result.socket) {
port.innerHTML = '<font color="#249400">ok</font>'; port.innerHTML = '<font style=\"color:#249400\">ok</font>';
} else { } else {
port.innerHTML = '<font color="#ff0000">fail</font>'; port.innerHTML = '<font style=\"color:#ff0000\">fail</font>';
} }
res(); res();
}); });

View File

@ -69,9 +69,9 @@ function export_ssr_url(btn, urlname, sid) {
textarea.select(); textarea.select();
try { try {
document.execCommand("copy"); // Security exception may be thrown by some browsers. document.execCommand("copy"); // Security exception may be thrown by some browsers.
s.innerHTML = "<font color='green'><%:Copy SSR to clipboard successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Copy SSR to clipboard successfully.%></font>";
} catch (ex) { } catch (ex) {
s.innerHTML = "<font color='red'><%:Unable to copy SSR to clipboard.%></font>"; s.innerHTML = "<font style=\'color:red\'><%:Unable to copy SSR to clipboard.%></font>";
} finally { } finally {
document.body.removeChild(textarea); document.body.removeChild(textarea);
} }
@ -83,7 +83,7 @@ function import_ssr_url(btn, urlname, sid) {
if (!s) return false; if (!s) return false;
var ssrurl = prompt("<%:Paste sharing link here%>", ""); var ssrurl = prompt("<%:Paste sharing link here%>", "");
if (ssrurl == null || ssrurl == "") { if (ssrurl == null || ssrurl == "") {
s.innerHTML = "<font color='red'><%:User cancelled.%></font>"; s.innerHTML = "<font style=\'color:red\'><%:User cancelled.%></font>";
return false; return false;
} }
s.innerHTML = ""; s.innerHTML = "";
@ -118,7 +118,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = params.get("insecure") ? true : false; document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = params.get("insecure") ? true : false;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "ss": case "ss":
var url0, param = ""; var url0, param = "";
@ -164,7 +164,7 @@ function import_ssr_url(btn, urlname, sid) {
if (param != undefined) { if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param); document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
} }
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
} else { } else {
var sstr = b64decsafe(url0); var sstr = b64decsafe(url0);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0]; document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
@ -179,7 +179,7 @@ function import_ssr_url(btn, urlname, sid) {
if (param != undefined) { if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param); document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
} }
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
} }
return false; return false;
case "ssr": case "ssr":
@ -212,7 +212,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam'); document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam');
var rem = pdict['remarks']; var rem = pdict['remarks'];
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem); if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem);
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "trojan": case "trojan":
try { try {
@ -234,7 +234,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = url.searchParams.get("sni"); document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = url.searchParams.get("sni");
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "vmess": case "vmess":
var sstr = b64DecodeUnicode(ssu[1]); var sstr = b64DecodeUnicode(ssu[1]);
@ -287,7 +287,7 @@ function import_ssr_url(btn, urlname, sid) {
} }
document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].checked = true; document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].dispatchEvent(event);
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "vless": case "vless":
try { try {
@ -357,10 +357,10 @@ function import_ssr_url(btn, urlname, sid) {
} }
break; break;
} }
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
default: default:
s.innerHTML = "<font color='red'><%:Invalid format.%></font>"; s.innerHTML = "<font style=\'color:red\'><%:Invalid format.%></font>";
return false; return false;
} }
} }

View File

@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=natflow PKG_NAME:=natflow
PKG_VERSION:=20240210 PKG_VERSION:=20240227
PKG_SOURCE_URL:=https://codeload.github.com/ptpt52/natflow/tar.gz/$(PKG_VERSION)? PKG_SOURCE_URL:=https://codeload.github.com/ptpt52/natflow/tar.gz/$(PKG_VERSION)?
PKG_HASH:=20dec9654f35214cc9bddc55837f6faf92227b88e315368dd1436cc893009662 PKG_HASH:=038e1a9351aaf052410140088aa402c1a1dcbba2d28a86cb64fe56d0cda226ce
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com> PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>

View File

@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=tailscale PKG_NAME:=tailscale
PKG_VERSION:=1.56.1 PKG_VERSION:=1.58.2
PKG_RELEASE:=2 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/tailscale/tailscale/tar.gz/v$(PKG_VERSION)? PKG_SOURCE_URL:=https://codeload.github.com/tailscale/tailscale/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=56b7d25c704e3c22e9e20dcb55695cd9c816878d2c172a73c64aac42e460fd41 PKG_HASH:=452f355408e4e2179872387a863387e06346fc8a6f9887821f9b8a072c6a5b0a
PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com> PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
PKG_LICENSE:=BSD-3-Clause PKG_LICENSE:=BSD-3-Clause

View File

@ -22,6 +22,8 @@ PKG_MAINTAINER:=sbwml <admin@cooluc.com>
PKG_BUILD_DEPENDS:=golang/host PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1 PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
PKG_BUILD_FLAGS:=no-mips16
GO_PKG:=github.com/urlesistiana/v2dat GO_PKG:=github.com/urlesistiana/v2dat