+ <% if container_running then %>
+
+ <% else %>
+
+ <% end %>
+
+
+<%
+if container_running then
+ local port=util.trim(util.exec("/usr/libexec/istorec/mfun.sh port"))
+ if port == "" then
+ port="8990"
+ end
+-%>
+
+
+
+
+
+
+
+<% end %>
\ No newline at end of file
diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile
index 2f70bdba..81662643 100644
--- a/luci-app-passwall/Makefile
+++ b/luci-app-passwall/Makefile
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.4.15
-PKG_RELEASE:=88
+PKG_RELEASE:=89
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
diff --git a/luci-app-passwall/root/etc/init.d/passwall b/luci-app-passwall/root/etc/init.d/passwall
index 97cbd906..189836f8 100755
--- a/luci-app-passwall/root/etc/init.d/passwall
+++ b/luci-app-passwall/root/etc/init.d/passwall
@@ -65,6 +65,15 @@ stop() {
restart() {
set_lock
[ $? == 1 ] && echolog "脚本已经在运行,不重复运行,退出." && exit 0
+ rule_lock=${LOCK_FILE_DIR}/${CONFIG}_rule_update.lock
+ sub_lock=${LOCK_FILE_DIR}/${CONFIG}_subscribe.lock
+ for i in $(seq 1 300); do
+ if [ ! -f "$rule_lock" ] && [ ! -f "$sub_lock" ]; then
+ break
+ fi
+ sleep 2
+ done
+ rm -f "$rule_lock" "$sub_lock"
$APP_FILE stop
$APP_FILE start $1
unset_lock
diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh
index 32c86282..7dd779a2 100755
--- a/luci-app-passwall/root/usr/share/passwall/app.sh
+++ b/luci-app-passwall/root/usr/share/passwall/app.sh
@@ -1558,7 +1558,7 @@ start_dns() {
start_adblock() {
[ "$(config_t_get global adblock 0)" != "1" ] && {
- [ -s $RULES_PATH/my_block_host ] && ln -sf $RULES_PATH/my_block_host $RULES_PATH/block_host
+ [ -s $RULES_PATH/my_block_host ] && ln -sf $RULES_PATH/my_block_host $RULES_PATH/block_host || echo "" >$RULES_PATH/block_host
return
}
"$APP_PATH/adblock.sh" > /dev/null 2>&1 &
diff --git a/luci-app-passwall/root/usr/share/passwall/rule_update.lua b/luci-app-passwall/root/usr/share/passwall/rule_update.lua
index d1528cc4..95358d6d 100755
--- a/luci-app-passwall/root/usr/share/passwall/rule_update.lua
+++ b/luci-app-passwall/root/usr/share/passwall/rule_update.lua
@@ -669,6 +669,34 @@ if geo2rule ~= "1" and gfwlist_update == "0" and chnroute_update == "0" and chnr
os.exit(0)
end
+local function check_instance(action)
+ local rule_lock = "/var/lock/" .. name .. "_rule_update.lock"
+ local sub_lock = "/var/lock/" .. name .. "_subscribe.lock"
+
+ if action == "start" then
+ math.randomseed(os.time() + math.floor(os.clock() * 1000))
+ api.nixio.nanosleep(0, math.random(100, 1000) * 1000000)
+ if fs.access(rule_lock) then
+ log("有[规则更新]实例正在运行,请稍后再试...\n")
+ os.exit(0)
+ else
+ luci.sys.call("touch " .. rule_lock)
+ end
+ elseif action == "end" then
+ luci.sys.call("rm -f " .. rule_lock)
+ return
+ end
+
+ if fs.access(sub_lock) then
+ log("[订阅]实例正在运行,[规则更新]进入队列等待...\n")
+ end
+ while fs.access(sub_lock) do
+ api.nixio.nanosleep(2, 0)
+ end
+end
+
+check_instance("start")
+
log("开始更新规则...")
local function safe_call(func, err_msg)
xpcall(func, function(e)
@@ -769,3 +797,5 @@ if reboot == 1 then
api.uci_save(uci, name, true, true)
end
log("规则更新完毕...\n")
+
+check_instance("end")
diff --git a/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/luci-app-passwall/root/usr/share/passwall/subscribe.lua
index fe2b26d0..87fd60bc 100755
--- a/luci-app-passwall/root/usr/share/passwall/subscribe.lua
+++ b/luci-app-passwall/root/usr/share/passwall/subscribe.lua
@@ -2174,20 +2174,30 @@ local execute = function()
end
end
-function check_instance(action)
- local lock_file = "/var/lock/" .. appname .. "_subscribe.lock"
+local function check_instance(action)
+ local sub_lock = "/var/lock/" .. appname .. "_subscribe.lock"
+ local rule_lock = "/var/lock/" .. appname .. "_rule_update.lock"
+
if action == "start" then
math.randomseed(os.time() + math.floor(os.clock() * 1000))
api.nixio.nanosleep(0, math.random(100, 1000) * 1000000)
- if fs.access(lock_file) then
- log("有订阅实例正在运行,请稍后再试...\n")
+ if fs.access(sub_lock) then
+ log("有[订阅]实例正在运行,请稍后再试...\n")
os.exit(0)
else
- luci.sys.call("touch " .. lock_file)
+ luci.sys.call("touch " .. sub_lock)
uci:revert(appname)
end
elseif action == "end" then
- luci.sys.call("rm -f " .. lock_file)
+ luci.sys.call("rm -f " .. sub_lock)
+ return
+ end
+
+ if fs.access(rule_lock) then
+ log("[规则更新]实例正在运行,[订阅]进入队列等待...\n")
+ end
+ while fs.access(rule_lock) do
+ api.nixio.nanosleep(2, 0)
end
end
diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile
index 13bd336f..37d4eec2 100644
--- a/luci-app-passwall2/Makefile
+++ b/luci-app-passwall2/Makefile
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=26.4.20
-PKG_RELEASE:=39
+PKG_RELEASE:=40
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
diff --git a/luci-app-passwall2/luasrc/controller/passwall2.lua b/luci-app-passwall2/luasrc/controller/passwall2.lua
index 66307151..40a868c1 100644
--- a/luci-app-passwall2/luasrc/controller/passwall2.lua
+++ b/luci-app-passwall2/luasrc/controller/passwall2.lua
@@ -659,7 +659,11 @@ function save_node_list_opt()
end
function update_rules()
- local update = http.formvalue("update")
+ local update = http.formvalue("update") or ""
+ if update == "" then
+ http_write_json_error({ message = "missing update target" })
+ return
+ end
luci.sys.call("lua /usr/share/passwall2/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &")
http_write_json()
end
diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm b/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm
index 67e147b1..09121425 100644
--- a/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm
+++ b/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm
@@ -298,7 +298,7 @@ table td, .table .td {
function to_add_node() {
ajaxAbortAll();
const dom = document.getElementsByClassName("cbi-tab")[0];
- const current_group = dom.getAttribute("group_name")
+ const current_group = dom ? (dom.getAttribute("group_name") || "default") : "default";
window.location.href='<%=api.url("add_node")%>?redirect=1&group=' + current_group;
}
diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua
index f2ab4f4a..f8a7f5bf 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua
+++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua
@@ -471,35 +471,35 @@ end
-- Processing data
local function processData(szType, content, add_mode, group, sub_cfg)
--log(2, content, add_mode, group)
- local default_allowinsecure = DEFAULT_ALLOWINSECURE
- local default_ss_type = DEFAULT_SS_TYPE
- local default_trojan_type = DEFAULT_TROJAN_TYPE
- local default_vmess_type = DEFAULT_VMESS_TYPE
- local default_vless_type = DEFAULT_VLESS_TYPE
- local default_hysteria2_type = DEFAULT_HYSTERIA2_TYPE
+ local sub_allowinsecure = DEFAULT_ALLOWINSECURE
+ local sub_ss_type = DEFAULT_SS_TYPE
+ local sub_trojan_type = DEFAULT_TROJAN_TYPE
+ local sub_vmess_type = DEFAULT_VMESS_TYPE
+ local sub_vless_type = DEFAULT_VLESS_TYPE
+ local sub_hysteria2_type = DEFAULT_HYSTERIA2_TYPE
if sub_cfg then
if sub_cfg.allowInsecure and sub_cfg.allowInsecure ~= "1" then
- default_allowinsecure = nil
+ sub_allowinsecure = nil
end
local ss_type = sub_cfg.ss_type or "global"
if ss_type ~= "global" and core_has[ss_type] then
- default_ss_type = ss_type
+ sub_ss_type = ss_type
end
local trojan_type = sub_cfg.trojan_type or "global"
if trojan_type ~= "global" and core_has[trojan_type] then
- default_trojan_type = trojan_type
+ sub_trojan_type = trojan_type
end
local vmess_type = sub_cfg.vmess_type or "global"
if vmess_type ~= "global" and core_has[vmess_type] then
- default_vmess_type = vmess_type
+ sub_vmess_type = vmess_type
end
local vless_type = sub_cfg.vless_type or "global"
if vless_type ~= "global" and core_has[vless_type] then
- default_vless_type = vless_type
+ sub_vless_type = vless_type
end
local hysteria2_type = sub_cfg.hysteria2_type or "global"
if hysteria2_type ~= "global" and core_has[hysteria2_type] then
- default_hysteria2_type = hysteria2_type
+ sub_hysteria2_type = hysteria2_type
end
end
local result = {
@@ -541,15 +541,14 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.remarks = base64Decode(params.remarks)
elseif szType == 'vmess' then
local info = jsonParse(content)
- if default_vmess_type == "sing-box" and has_singbox then
+ if sub_vmess_type == "sing-box" and has_singbox then
result.type = 'sing-box'
- elseif default_vmess_type == "xray" and has_xray then
+ elseif sub_vmess_type == "xray" and has_xray then
result.type = "Xray"
else
log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "VMess", "VMess"))
return nil
end
- result.alter_id = info.aid
result.address = info.add
result.port = info.port
result.protocol = 'vmess'
@@ -649,7 +648,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.tls_CertSha = info.pcs
result.tls_CertByName = info.vcn
local insecure = info.allowinsecure or info.allowInsecure or info.insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
else
result.tls = "0"
end
@@ -665,7 +664,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
return nil
end
elseif szType == "ss" then
- result = set_ss_implementation(default_ss_type, result)
+ result = set_ss_implementation(sub_ss_type, result)
if not result then return nil end
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
@@ -928,7 +927,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
end
end
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
result.uot = params.udp
elseif (params.type ~= "tcp" and params.type ~= "raw") and (params.headerType and params.headerType ~= "none") then
result.error_msg = i18n.translatef("Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks.")
@@ -937,7 +936,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
if params["shadow-tls"] then
if result.type ~= "sing-box" and result.type ~= "SS-Rust" then
- result.error_msg = default_ss_type .. " " .. i18n.translatef("unsupport %s plugin.", "shadow-tls")
+ result.error_msg = sub_ss_type .. " " .. i18n.translatef("unsupport %s plugin.", "shadow-tls")
else
-- Parsing SS Shadow-TLS plugin parameters
local function parseShadowTLSParams(b64str, out)
@@ -979,10 +978,10 @@ local function processData(szType, content, add_mode, group, sub_cfg)
end
end
elseif szType == "trojan" then
- if default_trojan_type == "sing-box" and has_singbox then
+ if sub_trojan_type == "sing-box" and has_singbox then
result.type = 'sing-box'
result.protocol = 'trojan'
- elseif default_trojan_type == "xray" and has_xray then
+ elseif sub_trojan_type == "xray" and has_xray then
result.type = 'Xray'
result.protocol = 'trojan'
else
@@ -1032,7 +1031,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.tls_CertSha = params.pcs
result.tls_CertByName = params.vcn
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
if not params.type then params.type = "tcp" end
params.type = string.lower(params.type)
@@ -1117,7 +1116,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
end
end
elseif szType == "ssd" then
- result = set_ss_implementation(default_ss_type, result)
+ result = set_ss_implementation(sub_ss_type, result)
if not result then return nil end
result.address = content.server
result.port = content.port
@@ -1128,9 +1127,9 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.group = content.airport
result.remarks = content.remarks
elseif szType == "vless" then
- if default_vless_type == "sing-box" and has_singbox then
+ if sub_vless_type == "sing-box" and has_singbox then
result.type = 'sing-box'
- elseif default_vless_type == "xray" and has_xray then
+ elseif sub_vless_type == "xray" and has_xray then
result.type = "Xray"
else
log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "VLESS", "VLESS"))
@@ -1283,7 +1282,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.reality_mldsa65Verify = params.pqv or nil
end
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
end
result.port = port
@@ -1340,7 +1339,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.hysteria_auth_password = params.auth
result.tls_serverName = params.peer or params.sni or ""
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
result.alpn = params.alpn
result.hysteria_up_mbps = params.upmbps
result.hysteria_down_mbps = params.downmbps
@@ -1386,12 +1385,12 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.tls_CertSha = params.pcs
result.tls_CertByName = params.vcn
local insecure = params.allowinsecure or params.insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
result.hysteria2_tls_pinSHA256 = params.pinSHA256
result.hysteria2_hop = params.mport
- if (default_hysteria2_type == "sing-box" and has_singbox) or (default_hysteria2_type == "xray" and has_xray) then
- local is_singbox = default_hysteria2_type == "sing-box" and has_singbox
+ if (sub_hysteria2_type == "sing-box" and has_singbox) or (sub_hysteria2_type == "xray" and has_xray) then
+ local is_singbox = sub_hysteria2_type == "sing-box" and has_singbox
result.type = is_singbox and 'sing-box' or 'Xray'
result.protocol = "hysteria2"
if params["obfs-password"] or params["obfs_password"] then
@@ -1466,7 +1465,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
result.tuic_congestion_control = params.congestion_control or "cubic"
result.tuic_udp_relay_mode = params.udp_relay_mode or "native"
local insecure = params.allowinsecure or params.insecure or params.allow_insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
elseif szType == "anytls" then
if has_singbox then
result.type = 'sing-box'
@@ -1530,7 +1529,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
end
result.port = port
local insecure = params.allowinsecure or params.insecure
- result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (default_allowinsecure and "1" or "0")
+ result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
end
elseif szType == 'naive+https' or szType == 'naive+quic' then
if has_singbox then