diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua
index 6a91ae4..f4c6393 100644
--- a/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/luci-app-passwall/luasrc/controller/passwall.lua
@@ -84,6 +84,8 @@ function index()
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
+ entry({"admin", "services", appname, "subscribe_manual"}, call("subscribe_manual")).leaf = true
+ entry({"admin", "services", appname, "subscribe_manual_all"}, call("subscribe_manual_all")).leaf = true
--[[rule_list]]
entry({"admin", "services", appname, "read_rulelist"}, call("read_rulelist")).leaf = true
@@ -721,3 +723,51 @@ function subscribe_del_all()
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1")
http.status(200, "OK")
end
+
+function subscribe_manual()
+ local section = http.formvalue("section") or ""
+ local current_url = http.formvalue("url") or ""
+ if section == "" or current_url == "" then
+ http_write_json({ success = false, msg = "Missing section or URL, skip." })
+ return
+ end
+ local uci_url = api.sh_uci_get(appname, section, "url")
+ if not uci_url or uci_url == "" then
+ http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
+ return
+ end
+ if uci_url ~= current_url then
+ api.sh_uci_set(appname, section, "url", current_url, true)
+ end
+ luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &")
+ http_write_json({ success = true, msg = "Subscribe triggered." })
+end
+
+function subscribe_manual_all()
+ local sections = http.formvalue("sections") or ""
+ local urls = http.formvalue("urls") or ""
+ if sections == "" or urls == "" then
+ http_write_json({ success = false, msg = "Missing section or URL, skip." })
+ return
+ end
+ local section_list = util.split(sections, ",")
+ local url_list = util.split(urls, ",")
+ -- 检查是否存在未保存配置
+ for i, section in ipairs(section_list) do
+ local uci_url = api.sh_uci_get(appname, section, "url")
+ if not uci_url or uci_url == "" then
+ http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
+ return
+ end
+ end
+ -- 保存有变动的url
+ for i, section in ipairs(section_list) do
+ local current_url = url_list[i] or ""
+ local uci_url = api.sh_uci_get(appname, section, "url")
+ if current_url ~= "" and uci_url ~= current_url then
+ api.sh_uci_set(appname, section, "url", current_url, true)
+ end
+ end
+ luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &")
+ http_write_json({ success = true, msg = "Subscribe triggered." })
+end
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua
index 9baef0d..9d56d48 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua
@@ -136,14 +136,15 @@ function o.cfgvalue(self, section)
translate("Delete All Subscribe Node"))
end
-o = s:option(Button, "_update", translate("Manual subscription All"))
-o.inputstyle = "apply"
-function o.write(t, n)
- luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual > /dev/null 2>&1 &")
- luci.http.redirect(api.url("log"))
+o = s:option(DummyValue, "_update", translate("Manual subscription All"))
+o.rawhtml = true
+o.cfgvalue = function(self, section)
+ return string.format([[
+ ]],
+ translate("Manual subscription All"))
end
-s = m:section(TypedSection, "subscribe_list", "", "" .. translate("Please input the subscription url first, save and submit before manual subscription.") .. "")
+s = m:section(TypedSection, "subscribe_list", "", "" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "")
s.addremove = true
s.anonymous = true
s.sortable = true
@@ -204,11 +205,12 @@ function o.cfgvalue(self, section)
remark, translate("Delete the subscribed node"))
end
-o = s:option(Button, "_update", translate("Manual subscription"))
-o.inputstyle = "apply"
-function o.write(t, n)
- luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. n .. " manual > /dev/null 2>&1 &")
- luci.http.redirect(api.url("log"))
+o = s:option(DummyValue, "_update", translate("Manual subscription"))
+o.rawhtml = true
+o.cfgvalue = function(self, section)
+ return string.format([[
+ ]],
+ section, translate("Manual subscription"))
end
s:append(Template(appname .. "/node_subscribe/js"))
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
index e943fc2..7e53d2d 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
@@ -132,7 +132,7 @@ if api.compare_versions(xray_version, ">=", "1.8.10") then
end
-- 探测地址
-local ucpu = s:option(Flag, _n("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 ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custom Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
ucpu:depends({ [_n("balancingStrategy")] = "leastLoad" })
@@ -373,6 +373,19 @@ o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translat
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
+o = s:option(Flag, _n("ech"), translate("ECH"))
+o.default = "0"
+o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
+
+o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
+o.default = ""
+o.rows = 5
+o.wrap = "soft"
+o:depends({ [_n("ech")] = true })
+o.validate = function(self, value)
+ return api.trim(value:gsub("[\r\n]", ""))
+end
+
-- [[ REALITY部分 ]] --
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
@@ -403,6 +416,19 @@ o.default = "chrome"
o:depends({ [_n("tls")] = true, [_n("utls")] = true })
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
+o = s:option(Flag, _n("use_mldsa65Verify"), translate("ML-DSA-65"))
+o.default = "0"
+o:depends({ [_n("tls")] = true, [_n("reality")] = true })
+
+o = s:option(TextValue, _n("reality_mldsa65Verify"), "ML-DSA-65 " .. translate("Public key"))
+o.default = ""
+o.rows = 5
+o.wrap = "soft"
+o:depends({ [_n("use_mldsa65Verify")] = true })
+o.validate = function(self, value)
+ return api.trim(value:gsub("[\r\n]", ""))
+end
+
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW (TCP)")
o:value("mkcp", "mKCP")
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua
index ffe1658..eed90f6 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua
@@ -465,14 +465,6 @@ o.validate = function(self, value)
return value
end
-o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
-o.default = "0"
-o:depends({ [_n("ech")] = true })
-
-o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
-o.default = "0"
-o:depends({ [_n("ech")] = true })
-
if singbox_tags:find("with_utls") then
o = s:option(Flag, _n("utls"), translate("uTLS"))
o.default = "0"
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
index 4b532b8..365d9c6 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
@@ -186,6 +186,19 @@ o:value("h2,http/1.1")
o:value("h3,h2,http/1.1")
o:depends({ [_n("tls")] = true })
+o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65"))
+o.default = "0"
+o:depends({ [_n("reality")] = true })
+
+o = s:option(TextValue, _n("reality_mldsa65Seed"), "ML-DSA-65 " .. translate("Private Key"))
+o.default = ""
+o.rows = 5
+o.wrap = "soft"
+o:depends({ [_n("use_mldsa65Seed")] = true })
+o.validate = function(self, value)
+ return api.trim(value:gsub("[\r\n]", ""))
+end
+
-- o = s:option(Value, _n("minversion"), translate("minversion"))
-- o.default = "1.3"
-- o:value("1.3")
@@ -223,6 +236,19 @@ o.validate = function(self, value, t)
return nil
end
+o = s:option(Flag, _n("ech"), translate("ECH"))
+o.default = "0"
+o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
+
+o = s:option(TextValue, _n("ech_key"), translate("ECH Key"))
+o.default = ""
+o.rows = 5
+o.wrap = "soft"
+o:depends({ [_n("ech")] = true })
+o.validate = function(self, value)
+ return api.trim(value:gsub("[\r\n]", ""))
+end
+
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW")
o:value("mkcp", "mKCP")
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/sing-box.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/sing-box.lua
index 92a6adc..ac53fb5 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/sing-box.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/sing-box.lua
@@ -323,14 +323,6 @@ o.validate = function(self, value)
return value
end
-o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
-o.default = "0"
-o:depends({ [_n("ech")] = true })
-
-o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
-o.default = "0"
-o:depends({ [_n("ech")] = true })
-
o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("tcp", "TCP")
o:value("http", "HTTP")
diff --git a/luci-app-passwall/luasrc/passwall/api.lua b/luci-app-passwall/luasrc/passwall/api.lua
index 772d881..2515f57 100644
--- a/luci-app-passwall/luasrc/passwall/api.lua
+++ b/luci-app-passwall/luasrc/passwall/api.lua
@@ -60,7 +60,8 @@ function uci_save(cursor, config, commit, apply)
end
function sh_uci_get(config, section, option)
- exec_call(string.format("uci -q get %s.%s.%s", config, section, option))
+ local _, val = exec_call(string.format("uci -q get %s.%s.%s", config, section, option))
+ return val
end
function sh_uci_set(config, section, option, val, commit)
diff --git a/luci-app-passwall/luasrc/passwall/com.lua b/luci-app-passwall/luasrc/passwall/com.lua
index 476874d..0b5b12e 100644
--- a/luci-app-passwall/luasrc/passwall/com.lua
+++ b/luci-app-passwall/luasrc/passwall/com.lua
@@ -1,11 +1,13 @@
local _M = {}
local function gh_release_url(self)
- return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
+ --return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
+ return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-release-api.json"
end
local function gh_pre_release_url(self)
- return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
+ --return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
+ return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json"
end
-- 排序顺序定义
diff --git a/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua
index 89b64bf..b0058fb 100644
--- a/luci-app-passwall/luasrc/passwall/util_sing-box.lua
+++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua
@@ -159,9 +159,7 @@ function gen_outbound(flag, node, tag, proxy_table)
--max_version = "1.3",
ech = {
enabled = (node.ech == "1") and true or false,
- config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
- pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
- dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
+ config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
},
utls = {
enabled = (node.utls == "1" or node.reality == "1") and true or false,
@@ -380,9 +378,7 @@ function gen_outbound(flag, node, tag, proxy_table)
} or nil,
ech = {
enabled = (node.ech == "1") and true or false,
- config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
- pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
- dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
+ config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
}
}
}
@@ -414,9 +410,7 @@ function gen_outbound(flag, node, tag, proxy_table)
} or nil,
ech = {
enabled = (node.ech == "1") and true or false,
- config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
- pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
- dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
+ config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
}
}
}
@@ -448,9 +442,7 @@ function gen_outbound(flag, node, tag, proxy_table)
insecure = (node.tls_allowInsecure == "1") and true or false,
ech = {
enabled = (node.ech == "1") and true or false,
- config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
- pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
- dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
+ config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
}
}
}
@@ -507,9 +499,7 @@ function gen_config_server(node)
if node.tls == "1" and node.ech == "1" then
tls.ech = {
enabled = true,
- key = node.ech_key and split(node.ech_key:gsub("\\n", "\n"), "\n") or {},
- pq_signature_schemes_enabled = (node.pq_signature_schemes_enabled == "1") and true or false,
- dynamic_record_sizing_disabled = (node.dynamic_record_sizing_disabled == "1") and true or false,
+ key = node.ech_key and split(node.ech_key:gsub("\\n", "\n"), "\n") or {}
}
end
diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua
index c9543bb..c7876e7 100644
--- a/luci-app-passwall/luasrc/passwall/util_xray.lua
+++ b/luci-app-passwall/luasrc/passwall/util_xray.lua
@@ -157,14 +157,16 @@ function gen_outbound(flag, node, tag, proxy_table)
tlsSettings = (node.stream_security == "tls") and {
serverName = node.tls_serverName,
allowInsecure = (node.tls_allowInsecure == "1") and true or false,
- fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil
+ fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil,
+ echConfigList = (node.ech == "1") and node.ech_config or nil
} or nil,
realitySettings = (node.stream_security == "reality") and {
serverName = node.tls_serverName,
publicKey = node.reality_publicKey,
shortId = node.reality_shortId or "",
spiderX = node.reality_spiderX or "/",
- fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome"
+ fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome",
+ mldsa65Verify = (node.use_mldsa65Verify == "1") and node.reality_mldsa65Verify or nil
} or nil,
rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and {
header = {
@@ -463,7 +465,8 @@ function gen_config_server(node)
certificateFile = node.tls_certificateFile,
keyFile = node.tls_keyFile
}
- }
+ },
+ echServerKeys = (node.ech == "1") and node.ech_key or nil
} or nil,
rawSettings = (node.transport == "raw" or node.transport == "tcp") and {
header = {
@@ -548,7 +551,8 @@ function gen_config_server(node)
dest = node.reality_dest,
serverNames = node.reality_serverNames or {},
privateKey = node.reality_private_key,
- shortIds = node.reality_shortId or ""
+ shortIds = node.reality_shortId or "",
+ mldsa65Seed = (node.use_mldsa65Seed == "1") and node.reality_mldsa65Seed or nil
} or nil
end
end
diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm b/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm
index 0b5c319..655253c 100644
--- a/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm
+++ b/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm
@@ -286,6 +286,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX");
+ params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
}
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value;
@@ -294,6 +295,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += "&security=" + v_security;
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName");
+ params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
+ params += opt.query("ech", dom_prefix + "ech_config");
}
if (opt.get(dom_prefix + "shadowtls")?.checked) {
@@ -461,6 +464,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX");
+ params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
}
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value;
@@ -470,6 +474,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
+ params += opt.query("ech", dom_prefix + "ech_config");
}
params += "#" + encodeURI(v_alias.value);
@@ -529,6 +534,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX");
+ params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
}
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value;
@@ -538,6 +544,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
+ params += opt.query("ech", dom_prefix + "ech_config");
}
params += "#" + encodeURI(v_alias.value);
if (params[0] == "&") {
@@ -968,6 +975,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'utls', true);
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
}
+ opt.set(dom_prefix + 'ech', !!queryParam.ech);
+ opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
}
if (queryParam.security == "reality") {
@@ -983,6 +992,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
+ opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
+ opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
}
}
@@ -1347,6 +1358,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'utls', true);
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
}
+ opt.set(dom_prefix + 'ech', !!queryParam.ech);
+ opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
}
if (queryParam.security == "reality") {
@@ -1362,6 +1375,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
+ opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
+ opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
}
}
diff --git a/luci-app-passwall/luasrc/view/passwall/node_subscribe/js.htm b/luci-app-passwall/luasrc/view/passwall/node_subscribe/js.htm
index 1dc361c..df28b84 100644
--- a/luci-app-passwall/luasrc/view/passwall/node_subscribe/js.htm
+++ b/luci-app-passwall/luasrc/view/passwall/node_subscribe/js.htm
@@ -3,6 +3,8 @@ local api = require "luci.passwall.api"
-%>
diff --git a/luci-app-passwall/po/zh-cn/passwall.po b/luci-app-passwall/po/zh-cn/passwall.po
index 0b76142..080f5c3 100644
--- a/luci-app-passwall/po/zh-cn/passwall.po
+++ b/luci-app-passwall/po/zh-cn/passwall.po
@@ -445,7 +445,7 @@ msgstr "负载均衡策略"
msgid "Fallback Node"
msgstr "后备节点"
-msgid "Use Custome Probe URL"
+msgid "Use Custom Probe URL"
msgstr "使用自定义探测网址"
msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL."
@@ -1072,8 +1072,14 @@ msgstr "订阅网址"
msgid "Subscribe URL Access Method"
msgstr "订阅网址访问方式"
-msgid "Please input the subscription url first, save and submit before manual subscription."
-msgstr "请输入订阅网址保存应用后再手动订阅。"
+msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically."
+msgstr "新增订阅请先保存并应用后再手动订阅;如仅修改订阅地址,可直接手动订阅,系统将自动保存。"
+
+msgid "Please save and apply before manually subscribing."
+msgstr "请先保存并应用后再手动订阅。"
+
+msgid "Subscribe URL cannot be empty."
+msgstr "订阅网址不能为空。"
msgid "Subscribe via proxy"
msgstr "通过代理订阅"
@@ -1706,16 +1712,10 @@ msgid "Protocol parameter. Enable length block encryption."
msgstr "协议参数。启用长度块加密。"
msgid "ECH Config"
-msgstr "ECH 密钥"
-
-msgid "ECH Key"
msgstr "ECH 配置"
-msgid "PQ signature schemes"
-msgstr "后量子对等证书签名方案"
-
-msgid "Disable adaptive sizing of TLS records"
-msgstr "禁用 TLS 记录的自适应大小调整"
+msgid "ECH Key"
+msgstr "ECH 密钥"
msgid "Enable Multipath TCP, need to be enabled in both server and client configuration."
msgstr "启用 Multipath TCP,需在服务端和客户端配置中同时启用。"
diff --git a/luci-app-passwall/root/usr/share/passwall/rules/direct_ip b/luci-app-passwall/root/usr/share/passwall/rules/direct_ip
index ada52ad..b73edaa 100644
--- a/luci-app-passwall/root/usr/share/passwall/rules/direct_ip
+++ b/luci-app-passwall/root/usr/share/passwall/rules/direct_ip
@@ -8,7 +8,3 @@
120.53.53.53
180.184.1.1
180.184.2.2
-203.208.39.192/28
-203.208.40.0/23
-34.149.0.0/16
-72.18.83.0/24
diff --git a/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/luci-app-passwall/root/usr/share/passwall/subscribe.lua
index 4ab75a1..0bcc4fe 100755
--- a/luci-app-passwall/root/usr/share/passwall/subscribe.lua
+++ b/luci-app-passwall/root/usr/share/passwall/subscribe.lua
@@ -820,11 +820,17 @@ local function processData(szType, content, add_mode, add_from)
result.utls = "1"
result.fingerprint = params.fp
end
+ if params.ech and params.ech ~= "" then
+ result.ech = "1"
+ result.ech_config = params.ech
+ end
if params.security == "reality" then
result.reality = "1"
result.reality_publicKey = params.pbk or nil
result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil
+ result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
+ result.reality_mldsa65Verify = params.pqv or nil
end
end
params.allowinsecure = params.allowinsecure or params.insecure
@@ -1196,11 +1202,17 @@ local function processData(szType, content, add_mode, add_from)
result.utls = "1"
result.fingerprint = params.fp
end
+ if params.ech and params.ech ~= "" then
+ result.ech = "1"
+ result.ech_config = params.ech
+ end
if params.security == "reality" then
result.reality = "1"
result.reality_publicKey = params.pbk or nil
result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil
+ result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
+ result.reality_mldsa65Verify = params.pqv or nil
end
end
@@ -1913,7 +1925,6 @@ local execute = function()
local raw_data = api.trim(stdout)
local old_md5 = value.md5 or ""
local new_md5 = luci.sys.exec("md5sum " .. tmp_file .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "")
- os.remove(tmp_file)
if not manual_sub and old_md5 == new_md5 then
log('订阅:【' .. remark .. '】没有变化,无需更新。')
else
@@ -1924,6 +1935,7 @@ local execute = function()
fail_list[#fail_list + 1] = value
end
end
+ luci.sys.call("rm -f " .. tmp_file)
allowInsecure_default = nil
filter_keyword_mode_default = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
filter_keyword_discard_list_default = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}