mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 02:11:19 +08:00
🦄 Sync 2026-04-07 20:32:07
This commit is contained in:
parent
5dddf79b1b
commit
6c4fe80788
@ -251,6 +251,7 @@ return dm2.dv.extend({
|
||||
let dnet = this.section.getOption('network').getUIElement(section_id).getValue();
|
||||
const disallowed = builtInNetworks.has(dnet);
|
||||
if (disallowed) return _('Only for user-defined networks');
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.option(form.Value, 'ipv4', _('IPv4 Address'));
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.1.1
|
||||
PKG_RELEASE:=2
|
||||
PKG_RELEASE:=3
|
||||
|
||||
LUCI_TITLE:=LuCI Support for momo
|
||||
LUCI_DEPENDS:=+luci-base +momo
|
||||
|
||||
@ -24,6 +24,34 @@ return view.extend({
|
||||
|
||||
m = new form.Map('momo');
|
||||
|
||||
s = m.section(form.NamedSection, 'log', 'log', _('Log Cleanup'));
|
||||
|
||||
o = s.option(form.Flag, 'log_cleanup_enabled', _('Scheduled Log Cleanup'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'log_cleanup_cron_expression', _('Log Cleanup Cron Expression'));
|
||||
o.retain = true;
|
||||
o.rmempty = false;
|
||||
o.placeholder = '0 4 * * *';
|
||||
o.depends('log_cleanup_enabled', '1');
|
||||
o.description = _('Run unconditional log cleanup at the configured cron schedule.');
|
||||
|
||||
o = s.option(form.Flag, 'log_cleanup_size_enabled', _('Size-based Log Cleanup'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'log_cleanup_size_check_cron_expression', _('Log Size Check Cron Expression'));
|
||||
o.retain = true;
|
||||
o.rmempty = false;
|
||||
o.placeholder = '*/30 * * * *';
|
||||
o.depends('log_cleanup_size_enabled', '1');
|
||||
o.description = _('Check log size at the configured cron schedule before cleaning up.');
|
||||
|
||||
o = s.option(form.Value, 'log_cleanup_size_mb', _('Log Cleanup Size Threshold (MB)'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '50';
|
||||
o.depends('log_cleanup_size_enabled', '1');
|
||||
o.description = _('Clear app, core and debug logs when their total size reaches this threshold.');
|
||||
|
||||
s = m.section(form.NamedSection, 'placeholder', 'placeholder', _('Log'));
|
||||
|
||||
s.tab('app_log', _('App Log'));
|
||||
@ -119,8 +147,5 @@ return view.extend({
|
||||
};
|
||||
|
||||
return m.render();
|
||||
},
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -425,3 +425,39 @@ msgstr ""
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:128
|
||||
msgid "procd Config"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:47
|
||||
msgid "Check log size at the configured cron schedule before cleaning up."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:53
|
||||
msgid "Clear app, core and debug logs when their total size reaches this threshold."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:27
|
||||
msgid "Log Cleanup"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:32
|
||||
msgid "Log Cleanup Cron Expression"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:49
|
||||
msgid "Log Cleanup Size Threshold (MB)"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:42
|
||||
msgid "Log Size Check Cron Expression"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:37
|
||||
msgid "Run unconditional log cleanup at the configured cron schedule."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:29
|
||||
msgid "Scheduled Log Cleanup"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:39
|
||||
msgid "Size-based Log Cleanup"
|
||||
msgstr ""
|
||||
|
||||
@ -432,3 +432,39 @@ msgstr "用户代理(UA)"
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:128
|
||||
msgid "procd Config"
|
||||
msgstr "procd 配置"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:47
|
||||
msgid "Check log size at the configured cron schedule before cleaning up."
|
||||
msgstr "按设定的 Cron 周期检查日志大小,满足条件后再清理。"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:53
|
||||
msgid "Clear app, core and debug logs when their total size reaches this threshold."
|
||||
msgstr "当插件日志、核心日志和调试日志总大小达到该阈值时自动清理。"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:27
|
||||
msgid "Log Cleanup"
|
||||
msgstr "日志清理"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:32
|
||||
msgid "Log Cleanup Cron Expression"
|
||||
msgstr "日志清理 Cron 表达式"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:49
|
||||
msgid "Log Cleanup Size Threshold (MB)"
|
||||
msgstr "日志清理大小阈值(MB)"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:42
|
||||
msgid "Log Size Check Cron Expression"
|
||||
msgstr "日志大小检查 Cron 表达式"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:37
|
||||
msgid "Run unconditional log cleanup at the configured cron schedule."
|
||||
msgstr "按设定的 Cron 时间无条件执行日志清理。"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:29
|
||||
msgid "Scheduled Log Cleanup"
|
||||
msgstr "定时日志清理"
|
||||
|
||||
#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:39
|
||||
msgid "Size-based Log Cleanup"
|
||||
msgstr "按大小触发日志清理"
|
||||
|
||||
@ -32,9 +32,10 @@ o = s:option(Value, _n("hop"), translate("Port hopping range"))
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o.rewrite_option = o.option
|
||||
|
||||
o = s:option(Value, _n("hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o.rewrite_option = o.option
|
||||
|
||||
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
|
||||
|
||||
@ -305,9 +305,10 @@ o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range"))
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||
|
||||
@ -278,9 +278,10 @@ if singbox_tags:find("with_quic") then
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o:depends({ [_n("protocol")] = "hysteria" })
|
||||
|
||||
o = s:option(Value, _n("hysteria_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hysteria_hop_interval"), translate("Hop Interval(second)"), translate("Example:") .. "30 (≥5)")
|
||||
o.datatype = "uinteger"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o:depends({ [_n("protocol")] = "hysteria" })
|
||||
|
||||
o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password"))
|
||||
@ -362,9 +363,10 @@ if singbox_tags:find("with_quic") then
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(Second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||
|
||||
@ -64,16 +64,27 @@ function gen_config(var)
|
||||
server = server,
|
||||
transport = {
|
||||
type = "udp",
|
||||
udp = {
|
||||
hopInterval = (function()
|
||||
local HopIntervalStr = tostring(node.hysteria2_hop_interval or "30s")
|
||||
local HopInterval = tonumber(HopIntervalStr:match("^%d+"))
|
||||
if HopInterval and HopInterval >= 5 then
|
||||
return tostring(HopInterval) .. "s"
|
||||
end
|
||||
return "30s"
|
||||
end)(),
|
||||
}
|
||||
udp = node.hysteria2_hop and (function()
|
||||
local udp = {}
|
||||
local t = node.hysteria2_hop_interval
|
||||
if not t then return nil end
|
||||
if t:find("-", 1, true) then
|
||||
local min, max = t:match("^(%d+)%-(%d+)$")
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
if min and max then
|
||||
min = (min >= 5) and min or 5
|
||||
max = (max >= min) and max or min
|
||||
udp.minHopInterval = min .. "s"
|
||||
udp.maxHopInterval = max .. "s"
|
||||
return udp
|
||||
end
|
||||
end
|
||||
t = tonumber((t or "30"):match("^%d+"))
|
||||
t = (t and t >= 5) and t or 30
|
||||
udp.hopInterval = t .. "s"
|
||||
return udp
|
||||
end)() or nil
|
||||
},
|
||||
obfs = (node.hysteria2_obfs) and {
|
||||
type = "salamander",
|
||||
|
||||
@ -421,7 +421,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
server_ports = next(server_ports) and server_ports or nil,
|
||||
hop_interval = (function()
|
||||
if not next(server_ports) then return nil end
|
||||
local v = tonumber((node.hysteria_hop_interval or "30s"):match("^%d+"))
|
||||
local v = tonumber((node.hysteria_hop_interval or "30"):match("^%d+"))
|
||||
return (v and v >= 5) and (v .. "s") or "30s"
|
||||
end)(),
|
||||
up_mbps = tonumber(node.hysteria_up_mbps),
|
||||
@ -474,13 +474,30 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
end
|
||||
end
|
||||
end
|
||||
local interval, interval_max
|
||||
if next(server_ports) then
|
||||
interval = "30s"
|
||||
local t = node.hysteria2_hop_interval or "30s"
|
||||
if t:find("-", 1, true) then
|
||||
local min, max = t:match("^(%d+)%-(%d+)$")
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
if min and max then
|
||||
min = (min >= 5) and min or 5
|
||||
max = (max >= min) and max or min
|
||||
interval = min .. "s"
|
||||
interval_max = max .. "s"
|
||||
end
|
||||
else
|
||||
t = tonumber(t:match("^%d+"))
|
||||
t = (t and t >= 5) and t or 30
|
||||
interval = t .. "s"
|
||||
end
|
||||
end
|
||||
protocol_table = {
|
||||
server_ports = next(server_ports) and server_ports or nil,
|
||||
hop_interval = (function()
|
||||
if not next(server_ports) then return nil end
|
||||
local v = tonumber((node.hysteria2_hop_interval or "30s"):match("^%d+"))
|
||||
return (v and v >= 5) and (v .. "s") or "30s"
|
||||
end)(),
|
||||
hop_interval = interval,
|
||||
hop_interval_max = interval_max,
|
||||
up_mbps = (node.hysteria2_up_mbps and tonumber(node.hysteria2_up_mbps)) and tonumber(node.hysteria2_up_mbps) or nil,
|
||||
down_mbps = (node.hysteria2_down_mbps and tonumber(node.hysteria2_down_mbps)) and tonumber(node.hysteria2_down_mbps) or nil,
|
||||
obfs = node.hysteria2_obfs_type and {
|
||||
|
||||
@ -284,7 +284,19 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
udpHop = (node.hysteria2_hop) and {
|
||||
ports = string.gsub(node.hysteria2_hop, ":", "-"),
|
||||
interval = (function(v)
|
||||
v = tonumber((v or "30s"):match("^%d+"))
|
||||
if not v then return 30 end
|
||||
if v:find("-", 1, true) then
|
||||
local min, max = v:match("^(%d+)%-(%d+)$")
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
if min and max then
|
||||
min = (min >= 5) and min or 5
|
||||
max = (max >= min) and max or min
|
||||
return min .. "-" .. max
|
||||
end
|
||||
return 30
|
||||
end
|
||||
v = tonumber((v or "30"):match("^%d+"))
|
||||
return (v and v >= 5) and v or 30
|
||||
end)(node.hysteria2_hop_interval)
|
||||
} or nil,
|
||||
|
||||
@ -962,7 +962,11 @@ table td, .table .td {
|
||||
} else {
|
||||
innerHTML = innerHTML.split("{{tcping}}").join('<span class="tcping_value" cbiid="{{id}}"><a href="javascript:void(0)" style="color:inherit">---</a></span>');
|
||||
}
|
||||
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping"><a href="javascript:void(0)" onclick="javascript:urltest_node(\'{{id}}\', this)" title="<%:TLS handshake test, latency for reference only%>"><%:Test%></a></span>');
|
||||
if (o["protocol"] && o["protocol"] !== '_shunt') {
|
||||
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping"><a href="javascript:void(0)" onclick="javascript:urltest_node(\'{{id}}\', this)" title="<%:TLS handshake test, latency for reference only%>"><%:Test%></a></span>');
|
||||
} else {
|
||||
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping" cbiid="{{id}}">---</span>');
|
||||
}
|
||||
innerHTML = innerHTML.split("{{id}}").join(o[".name"]);
|
||||
innerHTML = innerHTML.split("{{group}}").join(o["group"] || "");
|
||||
let node_remarks = get_remarks_name(o);
|
||||
|
||||
@ -1807,14 +1807,14 @@ msgstr "缓冲区大小"
|
||||
msgid "Buffer size for every connection (kB)"
|
||||
msgstr "每一个连接的缓冲区大小(kB)"
|
||||
|
||||
msgid "Handshake Timeout"
|
||||
msgstr "握手超时 "
|
||||
|
||||
msgid "Idle Timeout"
|
||||
msgstr "空闲超时 "
|
||||
msgstr "空闲超时"
|
||||
|
||||
msgid "Hop Interval"
|
||||
msgstr "端口跳跃时间 "
|
||||
msgid "Hop Interval(second)"
|
||||
msgstr "端口跳跃间隔(秒)"
|
||||
|
||||
msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."
|
||||
msgstr "支持固定值或随机范围(如 30 或 5-30),最小 5 秒。"
|
||||
|
||||
msgid "HeartbeatPeriod(second)"
|
||||
msgstr "心跳周期(单位:秒)"
|
||||
|
||||
@ -29,9 +29,10 @@ o = s:option(Value, _n("hop"), translate("Port hopping range"))
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o.rewrite_option = o.option
|
||||
|
||||
o = s:option(Value, _n("hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o.rewrite_option = o.option
|
||||
|
||||
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
|
||||
|
||||
@ -295,6 +295,7 @@ o = s:option(ListValue, _n("flow"), translate("flow"))
|
||||
o.default = ""
|
||||
o:value("", translate("Disable"))
|
||||
o:value("xtls-rprx-vision")
|
||||
o:value("xtls-rprx-vision-udp443")
|
||||
o:depends({ [_n("protocol")] = "vless" })
|
||||
|
||||
---- [[hysteria2]]
|
||||
@ -302,9 +303,10 @@ o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range"))
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||
|
||||
@ -315,9 +315,10 @@ if singbox_tags:find("with_quic") then
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o:depends({ [_n("protocol")] = "hysteria" })
|
||||
|
||||
o = s:option(Value, _n("hysteria_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hysteria_hop_interval"), translate("Hop Interval(second)"), translate("Example:") .. "30 (≥5)")
|
||||
o.datatype = "uinteger"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o:depends({ [_n("protocol")] = "hysteria" })
|
||||
|
||||
o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password"))
|
||||
@ -399,9 +400,10 @@ if singbox_tags:find("with_quic") then
|
||||
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
|
||||
o.placeholder = "30s"
|
||||
o.default = "30s"
|
||||
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(Second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.placeholder = "30"
|
||||
o.default = "30"
|
||||
o:depends({ [_n("protocol")] = "hysteria2" })
|
||||
|
||||
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||
|
||||
@ -1561,3 +1561,34 @@ function cleanEmptyTables(t)
|
||||
end
|
||||
return next(t) and t or nil
|
||||
end
|
||||
|
||||
function get_dnsmasq_server_domain()
|
||||
local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server")
|
||||
local dnsmasq_server_t = {}
|
||||
if dnsmasq_server and #dnsmasq_server > 0 then
|
||||
for k, v in ipairs(dnsmasq_server) do
|
||||
if v:find("/") then
|
||||
local split1 = split(v, "/")
|
||||
if #split1 > 2 then
|
||||
local domain = split1[2]
|
||||
local upstream_dns = split1[#split1]
|
||||
local upstream_dns_server
|
||||
local upstream_dns_port = "53"
|
||||
local dns_split = split(upstream_dns, "#")
|
||||
if #dns_split > 1 then
|
||||
upstream_dns_server = dns_split[1]
|
||||
upstream_dns_port = dns_split[#dns_split]
|
||||
else
|
||||
upstream_dns_server = upstream_dns
|
||||
end
|
||||
dnsmasq_server_t[domain] = {
|
||||
dnsmasq_dns = upstream_dns,
|
||||
server = upstream_dns_server,
|
||||
port = tonumber(upstream_dns_port)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return dnsmasq_server_t
|
||||
end
|
||||
@ -61,16 +61,27 @@ function gen_config(var)
|
||||
server = server,
|
||||
transport = {
|
||||
type = "udp",
|
||||
udp = {
|
||||
hopInterval = (function()
|
||||
local HopIntervalStr = tostring(node.hysteria2_hop_interval or "30s")
|
||||
local HopInterval = tonumber(HopIntervalStr:match("^%d+"))
|
||||
if HopInterval and HopInterval >= 5 then
|
||||
return tostring(HopInterval) .. "s"
|
||||
end
|
||||
return "30s"
|
||||
end)(),
|
||||
}
|
||||
udp = node.hysteria2_hop and (function()
|
||||
local udp = {}
|
||||
local t = node.hysteria2_hop_interval
|
||||
if not t then return nil end
|
||||
if t:find("-", 1, true) then
|
||||
local min, max = t:match("^(%d+)%-(%d+)$")
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
if min and max then
|
||||
min = (min >= 5) and min or 5
|
||||
max = (max >= min) and max or min
|
||||
udp.minHopInterval = min .. "s"
|
||||
udp.maxHopInterval = max .. "s"
|
||||
return udp
|
||||
end
|
||||
end
|
||||
t = tonumber((t or "30"):match("^%d+"))
|
||||
t = (t and t >= 5) and t or 30
|
||||
udp.hopInterval = t .. "s"
|
||||
return udp
|
||||
end)() or nil
|
||||
},
|
||||
obfs = (node.hysteria2_obfs) and {
|
||||
type = "salamander",
|
||||
|
||||
@ -153,7 +153,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
server = node.address,
|
||||
server_port = tonumber(node.port),
|
||||
domain_resolver = {
|
||||
server = "direct",
|
||||
server = "local",
|
||||
strategy = node.domain_strategy
|
||||
},
|
||||
detour = node.detour,
|
||||
@ -436,7 +436,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
server_ports = next(server_ports) and server_ports or nil,
|
||||
hop_interval = (function()
|
||||
if not next(server_ports) then return nil end
|
||||
local v = tonumber((node.hysteria_hop_interval or "30s"):match("^%d+"))
|
||||
local v = tonumber((node.hysteria_hop_interval or "30"):match("^%d+"))
|
||||
return (v and v >= 5) and (v .. "s") or "30s"
|
||||
end)(),
|
||||
up_mbps = tonumber(node.hysteria_up_mbps),
|
||||
@ -489,13 +489,30 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
end
|
||||
end
|
||||
end
|
||||
local interval, interval_max
|
||||
if next(server_ports) then
|
||||
interval = "30s"
|
||||
local t = node.hysteria2_hop_interval or "30s"
|
||||
if t:find("-", 1, true) then
|
||||
local min, max = t:match("^(%d+)%-(%d+)$")
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
if min and max then
|
||||
min = (min >= 5) and min or 5
|
||||
max = (max >= min) and max or min
|
||||
interval = min .. "s"
|
||||
interval_max = max .. "s"
|
||||
end
|
||||
else
|
||||
t = tonumber(t:match("^%d+"))
|
||||
t = (t and t >= 5) and t or 30
|
||||
interval = t .. "s"
|
||||
end
|
||||
end
|
||||
protocol_table = {
|
||||
server_ports = next(server_ports) and server_ports or nil,
|
||||
hop_interval = (function()
|
||||
if not next(server_ports) then return nil end
|
||||
local v = tonumber((node.hysteria2_hop_interval or "30s"):match("^%d+"))
|
||||
return (v and v >= 5) and (v .. "s") or "30s"
|
||||
end)(),
|
||||
hop_interval = interval,
|
||||
hop_interval_max = interval_max,
|
||||
up_mbps = (node.hysteria2_up_mbps and tonumber(node.hysteria2_up_mbps)) and tonumber(node.hysteria2_up_mbps) or nil,
|
||||
down_mbps = (node.hysteria2_down_mbps and tonumber(node.hysteria2_down_mbps)) and tonumber(node.hysteria2_down_mbps) or nil,
|
||||
obfs = node.hysteria2_obfs_type and {
|
||||
@ -901,7 +918,7 @@ function gen_config_server(node)
|
||||
outbound = require("luci.passwall2.util_sing-box").gen_outbound(nil, outbound_node_t, "outbound")
|
||||
end
|
||||
if outbound then
|
||||
route.final = "outbound"
|
||||
route.final = outbound.tag
|
||||
table.insert(outbounds, 1, outbound)
|
||||
end
|
||||
end
|
||||
@ -913,6 +930,14 @@ function gen_config_server(node)
|
||||
timestamp = true,
|
||||
--output = logfile,
|
||||
},
|
||||
dns = {
|
||||
servers = {
|
||||
{
|
||||
type = "local",
|
||||
tag = "local"
|
||||
}
|
||||
}
|
||||
},
|
||||
inbounds = { inbound },
|
||||
outbounds = outbounds,
|
||||
route = route
|
||||
@ -973,7 +998,7 @@ function gen_config(var)
|
||||
local no_run = var["no_run"]
|
||||
|
||||
local dns_domain_rules = {}
|
||||
local dns = nil
|
||||
local dns = {}
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local rule_set_table = {}
|
||||
@ -1661,16 +1686,21 @@ function gen_config(var)
|
||||
route.final = COMMON.default_outbound_tag
|
||||
end
|
||||
|
||||
if dns_listen_port then
|
||||
dns = {
|
||||
servers = {},
|
||||
rules = {},
|
||||
disable_cache = (dns_cache and dns_cache == "0") and true or false,
|
||||
disable_expire = false, -- Disable DNS cache expiration.
|
||||
independent_cache = false, -- Make each DNS server's cache independent for specific purposes. If enabled, it will slightly reduce performance.
|
||||
reverse_mapping = true, -- After responding to a DNS query, a reverse mapping of the IP address is stored to provide the domain name for routing purposes.
|
||||
}
|
||||
dns = {
|
||||
servers = {},
|
||||
rules = {},
|
||||
disable_cache = (dns_cache and dns_cache == "0") and true or false,
|
||||
disable_expire = false, -- Disable DNS cache expiration.
|
||||
independent_cache = false, -- Make each DNS server's cache independent for specific purposes. If enabled, it will slightly reduce performance.
|
||||
reverse_mapping = true, -- After responding to a DNS query, a reverse mapping of the IP address is stored to provide the domain name for routing purposes.
|
||||
}
|
||||
|
||||
table.insert(dns.servers, {
|
||||
type = "local",
|
||||
tag = "local"
|
||||
})
|
||||
|
||||
if dns_listen_port then
|
||||
local dns_host = ""
|
||||
if flag == "global" then
|
||||
dns_host = uci:get(appname, "@global[0]", "dns_hosts") or ""
|
||||
@ -1802,8 +1832,8 @@ function gen_config(var)
|
||||
end)
|
||||
if #domain > 0 then
|
||||
table.insert(dns_domain_rules, 1, {
|
||||
outboundTag = "direct",
|
||||
domain = domain
|
||||
domain = domain,
|
||||
outboundTag = "direct"
|
||||
})
|
||||
end
|
||||
|
||||
@ -1825,6 +1855,42 @@ function gen_config(var)
|
||||
})
|
||||
end
|
||||
|
||||
local dnsmasq_server_domain = api.get_dnsmasq_server_domain()
|
||||
if next(dnsmasq_server_domain) then
|
||||
local new_dns_servers = {}
|
||||
for domain, v in pairs(dnsmasq_server_domain) do
|
||||
if not new_dns_servers[v.dnsmasq_dns] then
|
||||
new_dns_servers[v.dnsmasq_dns] = {
|
||||
server = {
|
||||
tag = v.dnsmasq_dns,
|
||||
type = "udp",
|
||||
server = v.server,
|
||||
server_port = v.port,
|
||||
detour = "direct",
|
||||
},
|
||||
rule = {
|
||||
action = "route",
|
||||
domain_suffix = {},
|
||||
server = v.dnsmasq_dns,
|
||||
strategy = direct_strategy,
|
||||
},
|
||||
}
|
||||
end
|
||||
table.insert(new_dns_servers[v.dnsmasq_dns].rule.domain_suffix, domain)
|
||||
end
|
||||
for k, v in pairs(new_dns_servers) do
|
||||
table.insert(dns.servers, v.server)
|
||||
table.insert(dns.rules, 1, v.rule)
|
||||
table.insert(route.rules, 1, {
|
||||
action = "route",
|
||||
network = v.server.type,
|
||||
ip_cidr = v.server.server,
|
||||
port = v.server.server_port,
|
||||
outbound = "direct",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local default_dns_flag = "remote"
|
||||
if node_id and redir_port then
|
||||
local node = get_node_by_id(node_id)
|
||||
@ -1843,7 +1909,7 @@ function gen_config(var)
|
||||
if value.outboundTag and (value.domain or value.domain_suffix or value.domain_keyword or value.domain_regex or value.rule_set) then
|
||||
local dns_rule = {
|
||||
action = "route",
|
||||
server = value.outboundTag,
|
||||
server = value.server or value.outboundTag,
|
||||
domain = (value.domain and #value.domain > 0) and value.domain or nil,
|
||||
domain_suffix = (value.domain_suffix and #value.domain_suffix > 0) and value.domain_suffix or nil,
|
||||
domain_keyword = (value.domain_keyword and #value.domain_keyword > 0) and value.domain_keyword or nil,
|
||||
@ -1917,7 +1983,7 @@ function gen_config(var)
|
||||
listen_port = tonumber(dns_listen_port),
|
||||
}
|
||||
table.insert(inbounds, dns_in_inbound)
|
||||
table.insert(route.rules, {
|
||||
table.insert(route.rules, 1, {
|
||||
action = "sniff",
|
||||
inbound = dns_in_inbound.tag
|
||||
})
|
||||
@ -1961,15 +2027,6 @@ function gen_config(var)
|
||||
end
|
||||
end
|
||||
|
||||
if not dns then
|
||||
dns = {
|
||||
servers = {{
|
||||
type = "local",
|
||||
tag = "direct"
|
||||
}}
|
||||
}
|
||||
end
|
||||
|
||||
if next(ech_domain) ~= nil then
|
||||
table.insert(dns.servers, {
|
||||
tag = "ech-dns",
|
||||
@ -2018,7 +2075,7 @@ function gen_config(var)
|
||||
tag = "direct",
|
||||
routing_mark = 255,
|
||||
domain_resolver = {
|
||||
server = "direct",
|
||||
server = "local",
|
||||
strategy = "prefer_ipv6"
|
||||
}
|
||||
})
|
||||
@ -2026,6 +2083,9 @@ function gen_config(var)
|
||||
if not value["_flag_proxy_tag"] and not value.detour and value["_id"] and value.server and value.server_port and not no_run then
|
||||
sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
|
||||
end
|
||||
if value.detour then
|
||||
value.domain_resolver = nil
|
||||
end
|
||||
for k, v in pairs(config.outbounds[index]) do
|
||||
if k:find("_") == 1 then
|
||||
config.outbounds[index][k] = nil
|
||||
@ -2039,7 +2099,7 @@ function gen_config(var)
|
||||
if value.type == "wireguard" then
|
||||
-- https://sing-box.sagernet.org/migration/#migrate-wireguard-outbound-to-endpoint
|
||||
local endpoint = {
|
||||
type = "wireguard",
|
||||
type = value.type,
|
||||
tag = value.tag,
|
||||
system = value.system_interface,
|
||||
name = value.interface_name,
|
||||
@ -2056,10 +2116,7 @@ function gen_config(var)
|
||||
reserved = value.reserved
|
||||
}
|
||||
},
|
||||
domain_resolver = {
|
||||
server = "direct",
|
||||
strategy = value.domain_strategy
|
||||
},
|
||||
domain_resolver = value.domain_resolver,
|
||||
detour = value.detour
|
||||
}
|
||||
endpoints[#endpoints + 1] = endpoint
|
||||
|
||||
@ -280,7 +280,19 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
udpHop = (node.hysteria2_hop) and {
|
||||
ports = string.gsub(node.hysteria2_hop, ":", "-"),
|
||||
interval = (function(v)
|
||||
v = tonumber((v or "30s"):match("^%d+"))
|
||||
if not v then return 30 end
|
||||
if v:find("-", 1, true) then
|
||||
local min, max = v:match("^(%d+)%-(%d+)$")
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
if min and max then
|
||||
min = (min >= 5) and min or 5
|
||||
max = (max >= min) and max or min
|
||||
return min .. "-" .. max
|
||||
end
|
||||
return 30
|
||||
end
|
||||
v = tonumber((v or "30"):match("^%d+"))
|
||||
return (v and v >= 5) and v or 30
|
||||
end)(node.hysteria2_hop_interval)
|
||||
} or nil,
|
||||
@ -694,6 +706,14 @@ function gen_config_server(node)
|
||||
end
|
||||
end
|
||||
|
||||
for index, value in ipairs(config.outbounds) do
|
||||
for k, v in pairs(config.outbounds[index]) do
|
||||
if k:find("_") == 1 then
|
||||
config.outbounds[index][k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return config
|
||||
end
|
||||
|
||||
@ -734,7 +754,7 @@ function gen_config(var)
|
||||
local no_run = var["no_run"]
|
||||
|
||||
local dns_domain_rules = {}
|
||||
local dns = nil
|
||||
local dns = {}
|
||||
local fakedns = nil
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
@ -1063,17 +1083,17 @@ function gen_config(var)
|
||||
local to_node = get_node_by_id(node.to_node)
|
||||
if to_node then
|
||||
-- Landing Node not support use special node.
|
||||
if to_node.protocol:find("^_") then
|
||||
if to_node.protocol and to_node.protocol:find("^_") then
|
||||
to_node = nil
|
||||
end
|
||||
end
|
||||
if to_node then
|
||||
local to_outbound
|
||||
if to_node.type ~= "Xray" then
|
||||
local tag = to_node[".name"]
|
||||
local in_tag = "inbound_" .. to_node[".name"] .. "_" .. tostring(outbound.tag)
|
||||
local new_port = api.get_new_port()
|
||||
table.insert(inbounds, {
|
||||
tag = tag,
|
||||
tag = in_tag,
|
||||
listen = "127.0.0.1",
|
||||
port = new_port,
|
||||
protocol = "dokodemo-door",
|
||||
@ -1085,11 +1105,11 @@ function gen_config(var)
|
||||
to_node.address = "127.0.0.1"
|
||||
to_node.port = new_port
|
||||
table.insert(rules, 1, {
|
||||
inboundTag = {tag},
|
||||
inboundTag = {in_tag},
|
||||
outboundTag = outbound.tag
|
||||
})
|
||||
to_outbound = gen_outbound(node[".name"], to_node, tag, {
|
||||
tag = tag,
|
||||
to_outbound = gen_outbound(node[".name"], to_node, to_node[".name"], {
|
||||
tag = to_node[".name"],
|
||||
run_socks_instance = not no_run
|
||||
})
|
||||
else
|
||||
@ -1365,13 +1385,31 @@ function gen_config(var)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
dns = {
|
||||
tag = "dns-global",
|
||||
hosts = {},
|
||||
disableCache = (dns_cache and dns_cache == "0") and true or false,
|
||||
disableFallback = true,
|
||||
disableFallbackIfMatch = true,
|
||||
servers = {},
|
||||
queryStrategy = "UseIP"
|
||||
}
|
||||
|
||||
local dns_servers = {}
|
||||
|
||||
table.insert(dns_servers, {
|
||||
server = {
|
||||
tag = "local",
|
||||
address = "localhost"
|
||||
}
|
||||
})
|
||||
|
||||
if dns_listen_port then
|
||||
local direct_dns_tag = "dns-in-direct"
|
||||
local remote_dns_tag = "dns-in-remote"
|
||||
local remote_fakedns_tag = "dns-in-remote-fakedns"
|
||||
local default_dns_tag = "dns-in-default"
|
||||
local dns_servers = {}
|
||||
|
||||
local _remote_dns_proto = "tcp"
|
||||
|
||||
@ -1382,16 +1420,6 @@ function gen_config(var)
|
||||
}
|
||||
end
|
||||
|
||||
dns = {
|
||||
tag = "dns-global",
|
||||
hosts = {},
|
||||
disableCache = (dns_cache and dns_cache == "0") and true or false,
|
||||
disableFallback = true,
|
||||
disableFallbackIfMatch = true,
|
||||
servers = {},
|
||||
queryStrategy = "UseIP"
|
||||
}
|
||||
|
||||
local dns_host = ""
|
||||
if flag == "global" then
|
||||
dns_host = uci:get(appname, "@global[0]", "dns_hosts") or ""
|
||||
@ -1510,6 +1538,39 @@ function gen_config(var)
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local dnsmasq_server_domain = api.get_dnsmasq_server_domain()
|
||||
if next(dnsmasq_server_domain) then
|
||||
local new_dns_servers = {}
|
||||
for domain, v in pairs(dnsmasq_server_domain) do
|
||||
if not new_dns_servers[v.dnsmasq_dns] then
|
||||
new_dns_servers[v.dnsmasq_dns] = {
|
||||
server = {
|
||||
tag = v.dnsmasq_dns,
|
||||
address = v.server,
|
||||
port = v.port,
|
||||
queryStrategy = (direct_dns_query_strategy and direct_dns_query_strategy ~= "") and direct_dns_query_strategy or "UseIP"
|
||||
},
|
||||
domain = {}
|
||||
}
|
||||
end
|
||||
table.insert(new_dns_servers[v.dnsmasq_dns].domain, domain)
|
||||
end
|
||||
for k, v in pairs(new_dns_servers) do
|
||||
table.insert(dns_domain_rules, 1, {
|
||||
shunt_rule_name = k,
|
||||
outboundTag = "direct",
|
||||
dns_server = v.server,
|
||||
domain = v.domain
|
||||
})
|
||||
table.insert(routing.rules, 1, {
|
||||
network = "udp",
|
||||
ip = v.server.address,
|
||||
port = v.server.port,
|
||||
outboundTag = "direct"
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
if dns_listen_port then
|
||||
table.insert(inbounds, {
|
||||
@ -1590,7 +1651,9 @@ function gen_config(var)
|
||||
if value.domain and value.outboundTag then
|
||||
local dns_server = nil
|
||||
local dns_outboundTag = value.outboundTag
|
||||
if value.outboundTag == "direct" then
|
||||
if value.dns_server then
|
||||
dns_server = api.clone(value.dns_server)
|
||||
elseif value.outboundTag == "direct" then
|
||||
dns_server = api.clone(_direct_dns)
|
||||
else
|
||||
if value.fakedns then
|
||||
@ -1657,15 +1720,6 @@ function gen_config(var)
|
||||
table.insert(routing.rules, default_rule)
|
||||
end
|
||||
|
||||
local dns_hosts_len = 0
|
||||
for key, value in pairs(dns.hosts) do
|
||||
dns_hosts_len = dns_hosts_len + 1
|
||||
end
|
||||
|
||||
if dns_hosts_len == 0 then
|
||||
dns.hosts = nil
|
||||
end
|
||||
|
||||
local content = flag .. node_id .. jsonc.stringify(routing.rules)
|
||||
if api.cacheFileCompareToLogic(CACHE_TEXT_FILE, content) == false then
|
||||
--clear ipset/nftset
|
||||
@ -1701,6 +1755,10 @@ function gen_config(var)
|
||||
end
|
||||
end
|
||||
|
||||
if not next(dns.hosts) then
|
||||
dns.hosts = nil
|
||||
end
|
||||
|
||||
if redir_port then
|
||||
local inbound = {
|
||||
port = tonumber(redir_port),
|
||||
|
||||
@ -1455,7 +1455,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'port', m.port || "443");
|
||||
|
||||
opt.set(dom_prefix + 'encryption', queryParam.encryption || "none");
|
||||
opt.set(dom_prefix + 'flow', (queryParam.flow || '').replace('-udp443', ''));
|
||||
opt.set(dom_prefix + 'flow', queryParam.flow || '');
|
||||
if (queryParam.security) {
|
||||
if (queryParam.security == "tls") {
|
||||
opt.set(dom_prefix + 'tls', true);
|
||||
|
||||
@ -963,7 +963,11 @@ table td, .table .td {
|
||||
} else {
|
||||
innerHTML = innerHTML.split("{{tcping}}").join('<span class="tcping_value" cbiid="{{id}}"><a href="javascript:void(0)" style="color:inherit">---</a></span>');
|
||||
}
|
||||
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping"><a href="javascript:void(0)" onclick="javascript:urltest_node(\'{{id}}\', this)"><%:Test%></a></span>');
|
||||
if (o["address"] && o["port"]) {
|
||||
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping"><a href="javascript:void(0)" onclick="javascript:urltest_node(\'{{id}}\', this)"><%:Test%></a></span>');
|
||||
} else {
|
||||
innerHTML = innerHTML.split("{{url_test}}").join('<span class="ping_value"><a href="javascript:void(0)" style="color:inherit">---</a></span>');
|
||||
}
|
||||
innerHTML = innerHTML.split("{{id}}").join(o[".name"]);
|
||||
innerHTML = innerHTML.split("{{group}}").join(o["group"] || "");
|
||||
let node_remarks = get_remarks_name(o);
|
||||
|
||||
@ -1638,14 +1638,14 @@ msgstr "اندازه بافر"
|
||||
msgid "Buffer size for every connection (kB)"
|
||||
msgstr "اندازه بافر برای هر اتصال (کیلوبایت)"
|
||||
|
||||
msgid "Handshake Timeout"
|
||||
msgstr "مهلت زمانی دست تکان دادن"
|
||||
|
||||
msgid "Idle Timeout"
|
||||
msgstr "مهلت زمانی بیکاری"
|
||||
|
||||
msgid "Hop Interval"
|
||||
msgstr "بازه پرش (Hop)"
|
||||
msgid "Hop Interval(second)"
|
||||
msgstr "فاصله پرش (ثانیه)"
|
||||
|
||||
msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."
|
||||
msgstr "از یک مقدار ثابت یا یک محدوده تصادفی (مثلاً 30، 5-30)، حداقل 5، پشتیبانی میکند."
|
||||
|
||||
msgid "HeartbeatPeriod(second)"
|
||||
msgstr "دوره ضربان قلب (ثانیه)"
|
||||
|
||||
@ -1639,14 +1639,14 @@ msgstr "Размер буфера"
|
||||
msgid "Buffer size for every connection (kB)"
|
||||
msgstr "Размер буфера для каждого соединения (КБ)"
|
||||
|
||||
msgid "Handshake Timeout"
|
||||
msgstr "Тайм-аут рукопожатия"
|
||||
|
||||
msgid "Idle Timeout"
|
||||
msgstr "Тайм-аут простоя"
|
||||
|
||||
msgid "Hop Interval"
|
||||
msgstr "Интервал смены порта"
|
||||
msgid "Hop Interval(second)"
|
||||
msgstr "Интервал прыжков (секунды)"
|
||||
|
||||
msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."
|
||||
msgstr "Поддерживается фиксированное значение или случайный диапазон (например, 30, 5-30), минимум 5."
|
||||
|
||||
msgid "HeartbeatPeriod(second)"
|
||||
msgstr "Период heartbeat-пакетов (сек)"
|
||||
|
||||
@ -1630,14 +1630,14 @@ msgstr "缓冲区大小"
|
||||
msgid "Buffer size for every connection (kB)"
|
||||
msgstr "每一个连接的缓冲区大小(kB)"
|
||||
|
||||
msgid "Handshake Timeout"
|
||||
msgstr "握手超时 "
|
||||
|
||||
msgid "Idle Timeout"
|
||||
msgstr "空闲超时 "
|
||||
msgstr "空闲超时"
|
||||
|
||||
msgid "Hop Interval"
|
||||
msgstr "端口跳跃时间 "
|
||||
msgid "Hop Interval(second)"
|
||||
msgstr "端口跳跃间隔(秒)"
|
||||
|
||||
msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."
|
||||
msgstr "支持固定值或随机范围(如 30 或 5-30),最小 5 秒。"
|
||||
|
||||
msgid "HeartbeatPeriod(second)"
|
||||
msgstr "心跳周期(单位:秒)"
|
||||
|
||||
@ -1630,14 +1630,14 @@ msgstr "缓衝区大小"
|
||||
msgid "Buffer size for every connection (kB)"
|
||||
msgstr "每一個連接的缓衝区大小(kB)"
|
||||
|
||||
msgid "Handshake Timeout"
|
||||
msgstr "握手超時 "
|
||||
|
||||
msgid "Idle Timeout"
|
||||
msgstr "空闲超時 "
|
||||
msgstr "空闲超時"
|
||||
|
||||
msgid "Hop Interval"
|
||||
msgstr "端口跳跃時間 "
|
||||
msgid "Hop Interval(second)"
|
||||
msgstr "端口跳躍間隔(秒)"
|
||||
|
||||
msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5."
|
||||
msgstr "支援固定值或隨機範圍(如 30 或 5-30),最小 5 秒。"
|
||||
|
||||
msgid "HeartbeatPeriod(second)"
|
||||
msgstr "心跳周期(單位:秒)"
|
||||
|
||||
@ -1169,6 +1169,7 @@ start() {
|
||||
export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET
|
||||
export ENABLE_DEPRECATED_GEOSITE=true
|
||||
export ENABLE_DEPRECATED_GEOIP=true
|
||||
export SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN=1
|
||||
ulimit -n 65535
|
||||
start_haproxy
|
||||
start_socks
|
||||
@ -1237,6 +1238,7 @@ stop() {
|
||||
pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua|tasks\.sh|server_app\.lua|ujail/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
unset V2RAY_LOCATION_ASSET
|
||||
unset XRAY_LOCATION_ASSET
|
||||
unset SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN
|
||||
stop_crontab
|
||||
rm -rf $GLOBAL_DNSMASQ_CONF
|
||||
rm -rf $GLOBAL_DNSMASQ_CONF_PATH
|
||||
|
||||
@ -272,7 +272,7 @@ function add_rule(var)
|
||||
local function process_address(address)
|
||||
if address == "engage.cloudflareclient.com" then return end
|
||||
if datatypes.hostname(address) then
|
||||
set_domain_dns(address, fwd_dns)
|
||||
--set_domain_dns(address, fwd_dns)
|
||||
set_domain_ipset(address, setflag_4 .. "passwall2_vps," .. setflag_6 .. "passwall2_vps6")
|
||||
end
|
||||
end
|
||||
|
||||
@ -1216,10 +1216,8 @@ local function processData(szType, content, add_mode, group)
|
||||
result.httpupgrade_host = params.host
|
||||
result.httpupgrade_path = params.path
|
||||
end
|
||||
|
||||
result.encryption = params.encryption or "none"
|
||||
|
||||
result.flow = params.flow and params.flow:gsub("-udp443", "") or nil
|
||||
result.flow = params.flow
|
||||
|
||||
result.tls = "0"
|
||||
if params.security == "tls" or params.security == "reality" then
|
||||
|
||||
@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=momo
|
||||
PKG_VERSION:=2026.03.29
|
||||
PKG_RELEASE:=4
|
||||
PKG_RELEASE:=5
|
||||
|
||||
PKG_LICENSE:=GPL-3.0+
|
||||
PKG_MAINTAINER:=Joseph Mory <morytyann@gmail.com>
|
||||
|
||||
@ -8,6 +8,13 @@ config config 'config'
|
||||
option 'test_profile' '1'
|
||||
option 'core_only' '0'
|
||||
|
||||
config log 'log'
|
||||
option 'log_cleanup_enabled' '0'
|
||||
option 'log_cleanup_cron_expression' '0 4 * * *'
|
||||
option 'log_cleanup_size_enabled' '0'
|
||||
option 'log_cleanup_size_check_cron_expression' '*/30 * * * *'
|
||||
option 'log_cleanup_size_mb' '50'
|
||||
|
||||
config procd 'procd'
|
||||
option 'fast_reload' '0'
|
||||
|
||||
|
||||
@ -9,6 +9,8 @@ PROG="/usr/bin/sing-box"
|
||||
. "$IPKG_INSTROOT/etc/momo/scripts/include.sh"
|
||||
|
||||
extra_command 'update_subscription' 'Update subscription by section id'
|
||||
extra_command 'cleanup_logs' 'Cleanup logs immediately'
|
||||
extra_command 'check_log_cleanup' 'Cleanup logs if size threshold is reached'
|
||||
|
||||
boot_func() {
|
||||
# prepare files
|
||||
@ -56,11 +58,17 @@ start_service() {
|
||||
# get config
|
||||
## app config
|
||||
local scheduled_restart cron_expression profile test_profile core_only
|
||||
local log_cleanup_enabled log_cleanup_cron_expression log_cleanup_size_enabled log_cleanup_size_check_cron_expression log_cleanup_size_mb
|
||||
config_get_bool scheduled_restart "config" "scheduled_restart" 0
|
||||
config_get cron_expression "config" "cron_expression"
|
||||
config_get profile "config" "profile"
|
||||
config_get_bool test_profile "config" "test_profile" 0
|
||||
config_get_bool core_only "config" "core_only" 0
|
||||
config_get_bool log_cleanup_enabled "log" "log_cleanup_enabled" 0
|
||||
config_get log_cleanup_cron_expression "log" "log_cleanup_cron_expression"
|
||||
config_get_bool log_cleanup_size_enabled "log" "log_cleanup_size_enabled" 0
|
||||
config_get log_cleanup_size_check_cron_expression "log" "log_cleanup_size_check_cron_expression"
|
||||
config_get log_cleanup_size_mb "log" "log_cleanup_size_mb" 0
|
||||
## procd config
|
||||
### general
|
||||
local fast_reload
|
||||
@ -194,9 +202,23 @@ start_service() {
|
||||
|
||||
procd_close_instance
|
||||
# cron
|
||||
local cron_reload; cron_reload=0
|
||||
if [ "$scheduled_restart" = 1 ] && [ -n "$cron_expression" ]; then
|
||||
log "App" "Set scheduled restart."
|
||||
echo "$cron_expression /etc/init.d/momo restart #momo" >> "/etc/crontabs/root"
|
||||
echo "$cron_expression /etc/init.d/momo restart #momo_scheduled_restart" >> "/etc/crontabs/root"
|
||||
cron_reload=1
|
||||
fi
|
||||
if [ "$log_cleanup_enabled" = 1 ] && [ -n "$log_cleanup_cron_expression" ]; then
|
||||
log "Log" "Set scheduled log cleanup."
|
||||
echo "$log_cleanup_cron_expression /etc/init.d/momo cleanup_logs > /dev/null 2>&1 #momo_log_cleanup_time" >> "/etc/crontabs/root"
|
||||
cron_reload=1
|
||||
fi
|
||||
if [ "$log_cleanup_size_enabled" = 1 ] && [ -n "$log_cleanup_size_check_cron_expression" ] && [ "${log_cleanup_size_mb:-0}" -gt 0 ]; then
|
||||
log "Log" "Set size-based log cleanup check."
|
||||
echo "$log_cleanup_size_check_cron_expression /etc/init.d/momo check_log_cleanup > /dev/null 2>&1 #momo_log_cleanup_size" >> "/etc/crontabs/root"
|
||||
cron_reload=1
|
||||
fi
|
||||
if [ "$cron_reload" = 1 ]; then
|
||||
/etc/init.d/cron restart
|
||||
fi
|
||||
# set started flag
|
||||
@ -405,6 +427,46 @@ cleanup() {
|
||||
/etc/init.d/cron restart
|
||||
}
|
||||
|
||||
cleanup_logs() {
|
||||
prepare_files
|
||||
run_log_cleanup "scheduled trigger"
|
||||
}
|
||||
|
||||
check_log_cleanup() {
|
||||
prepare_files
|
||||
config_load momo
|
||||
|
||||
local log_cleanup_size_enabled log_cleanup_size_mb total_size_bytes threshold_size_bytes
|
||||
config_get_bool log_cleanup_size_enabled "log" "log_cleanup_size_enabled" 0
|
||||
config_get log_cleanup_size_mb "log" "log_cleanup_size_mb" 0
|
||||
|
||||
if [ "$log_cleanup_size_enabled" != 1 ] || [ "${log_cleanup_size_mb:-0}" -le 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
total_size_bytes=$(get_total_log_size)
|
||||
threshold_size_bytes=$((log_cleanup_size_mb * 1024 * 1024))
|
||||
|
||||
if [ "$total_size_bytes" -lt "$threshold_size_bytes" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
run_log_cleanup "size threshold ${log_cleanup_size_mb} MB reached" "$total_size_bytes"
|
||||
}
|
||||
|
||||
run_log_cleanup() {
|
||||
local reason previous_size
|
||||
reason="$1"
|
||||
previous_size="$2"
|
||||
|
||||
if [ -z "$previous_size" ]; then
|
||||
previous_size=$(get_total_log_size)
|
||||
fi
|
||||
|
||||
clear_log
|
||||
log "Log" "Cleanup executed: ${reason}. Previous total size: $(format_filesize "$previous_size")."
|
||||
}
|
||||
|
||||
update_subscription() {
|
||||
local subscription_section; subscription_section="$1"
|
||||
if [ -z "$subscription_section" ]; then
|
||||
|
||||
@ -118,6 +118,9 @@ prepare_files() {
|
||||
if [ ! -f "$CORE_LOG_PATH" ]; then
|
||||
touch "$CORE_LOG_PATH"
|
||||
fi
|
||||
if [ ! -f "$DEBUG_LOG_PATH" ]; then
|
||||
touch "$DEBUG_LOG_PATH"
|
||||
fi
|
||||
if [ ! -d "$TEMP_DIR" ]; then
|
||||
mkdir -p "$TEMP_DIR"
|
||||
fi
|
||||
@ -126,6 +129,26 @@ prepare_files() {
|
||||
clear_log() {
|
||||
echo -n > "$APP_LOG_PATH"
|
||||
echo -n > "$CORE_LOG_PATH"
|
||||
echo -n > "$DEBUG_LOG_PATH"
|
||||
}
|
||||
|
||||
get_filesize() {
|
||||
local path; path="$1"
|
||||
if [ ! -f "$path" ]; then
|
||||
echo 0
|
||||
return
|
||||
fi
|
||||
wc -c < "$path" | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
get_total_log_size() {
|
||||
local total_size path path_size
|
||||
total_size=0
|
||||
for path in "$APP_LOG_PATH" "$CORE_LOG_PATH" "$DEBUG_LOG_PATH"; do
|
||||
path_size=$(get_filesize "$path")
|
||||
total_size=$((total_size + path_size))
|
||||
done
|
||||
echo "$total_size"
|
||||
}
|
||||
|
||||
log() {
|
||||
|
||||
@ -25,6 +25,45 @@ procd=$(uci -q get momo.procd); [ -z "$procd" ] && {
|
||||
|
||||
dummy_device=$(uci -q get momo.routing.dummy_device); [ -z "$dummy_device" ] && uci set momo.routing.dummy_device=momo-dummy
|
||||
|
||||
# since v1.1.2
|
||||
|
||||
section_log=$(uci -q get momo.log); [ -z "$section_log" ] && uci set momo.log=log
|
||||
|
||||
log_cleanup_enabled=$(uci -q get momo.log.log_cleanup_enabled)
|
||||
[ -z "$log_cleanup_enabled" ] && {
|
||||
log_cleanup_enabled=$(uci -q get momo.config.log_cleanup_enabled)
|
||||
[ -n "$log_cleanup_enabled" ] && uci set momo.log.log_cleanup_enabled=$log_cleanup_enabled || uci set momo.log.log_cleanup_enabled=0
|
||||
}
|
||||
uci -q del momo.config.log_cleanup_enabled
|
||||
|
||||
log_cleanup_cron_expression=$(uci -q get momo.log.log_cleanup_cron_expression)
|
||||
[ -z "$log_cleanup_cron_expression" ] && {
|
||||
log_cleanup_cron_expression=$(uci -q get momo.config.log_cleanup_cron_expression)
|
||||
[ -n "$log_cleanup_cron_expression" ] && uci set momo.log.log_cleanup_cron_expression="$log_cleanup_cron_expression" || uci set momo.log.log_cleanup_cron_expression='0 4 * * *'
|
||||
}
|
||||
uci -q del momo.config.log_cleanup_cron_expression
|
||||
|
||||
log_cleanup_size_enabled=$(uci -q get momo.log.log_cleanup_size_enabled)
|
||||
[ -z "$log_cleanup_size_enabled" ] && {
|
||||
log_cleanup_size_enabled=$(uci -q get momo.config.log_cleanup_size_enabled)
|
||||
[ -n "$log_cleanup_size_enabled" ] && uci set momo.log.log_cleanup_size_enabled=$log_cleanup_size_enabled || uci set momo.log.log_cleanup_size_enabled=0
|
||||
}
|
||||
uci -q del momo.config.log_cleanup_size_enabled
|
||||
|
||||
log_cleanup_size_check_cron_expression=$(uci -q get momo.log.log_cleanup_size_check_cron_expression)
|
||||
[ -z "$log_cleanup_size_check_cron_expression" ] && {
|
||||
log_cleanup_size_check_cron_expression=$(uci -q get momo.config.log_cleanup_size_check_cron_expression)
|
||||
[ -n "$log_cleanup_size_check_cron_expression" ] && uci set momo.log.log_cleanup_size_check_cron_expression="$log_cleanup_size_check_cron_expression" || uci set momo.log.log_cleanup_size_check_cron_expression='*/30 * * * *'
|
||||
}
|
||||
uci -q del momo.config.log_cleanup_size_check_cron_expression
|
||||
|
||||
log_cleanup_size_mb=$(uci -q get momo.log.log_cleanup_size_mb)
|
||||
[ -z "$log_cleanup_size_mb" ] && {
|
||||
log_cleanup_size_mb=$(uci -q get momo.config.log_cleanup_size_mb)
|
||||
[ -n "$log_cleanup_size_mb" ] && uci set momo.log.log_cleanup_size_mb=$log_cleanup_size_mb || uci set momo.log.log_cleanup_size_mb=50
|
||||
}
|
||||
uci -q del momo.config.log_cleanup_size_mb
|
||||
|
||||
# commit
|
||||
uci commit momo
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user