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 6140f7bcb..9f0868a80 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
@@ -49,7 +49,9 @@ o:depends({ [option_name("protocol")] = "_iface" })
local nodes_table = {}
local balancers_table = {}
+local fallback_table = {}
local iface_table = {}
+local is_balancer = nil
for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then
nodes_table[#nodes_table + 1] = {
@@ -63,6 +65,15 @@ for k, e in ipairs(api.get_valid_nodes()) do
id = e[".name"],
remark = e["remark"]
}
+ if e[".name"] ~= arg[1] then
+ fallback_table[#fallback_table + 1] = {
+ id = e[".name"],
+ remark = e["remark"],
+ fallback = e["fallback_node"]
+ }
+ else
+ is_balancer = true
+ end
end
if e.protocol == "_iface" then
iface_table[#iface_table + 1] = {
@@ -90,23 +101,35 @@ for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end
local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balancing Strategy"))
o:depends({ [option_name("protocol")] = "_balancing" })
o:value("random")
+o:value("roundRobin")
o:value("leastPing")
-o:value("leastLoad")
-o.default = "leastLoad"
+o.default = "leastPing"
-- Fallback Node
if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.10") then
local o = s:option(ListValue, option_name("fallback_node"), translate("Fallback Node"))
- o:depends({ [option_name("protocol")] = "_balancing" })
+ o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o:value("",translate("Null"))
o.default = ""
+ local function check_fallback_chain(fb)
+ for k, v in pairs(fallback_table) do
+ if v.fallback == fb then
+ fallback_table[k] = nil
+ check_fallback_chain(v.id)
+ end
+ end
+ end
+ -- 检查fallback链,去掉会形成闭环的balancer节点
+ if is_balancer then
+ check_fallback_chain(arg[1])
+ end
+ for k, v in pairs(fallback_table) do o:value(v.id, v.remark) end
for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end
end
-- 探测地址
local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
-o:depends({ [option_name("balancingStrategy")] = "leastLoad" })
local o = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
o:depends({ [option_name("useCustomProbeUrl")] = true })
@@ -116,7 +139,6 @@ o.description = translate("The URL used to detect the connection status.")
-- 探测间隔
local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
-o:depends({ [option_name("balancingStrategy")] = "leastLoad" })
o.default = "1m"
o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are ns
, us
, ms
, s
, m
, h
, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua
index 9c1e13541..7121f2fb4 100644
--- a/luci-app-passwall/luasrc/passwall/util_xray.lua
+++ b/luci-app-passwall/luasrc/passwall/util_xray.lua
@@ -564,6 +564,8 @@ function gen_config(var)
if node_id then
local node = uci:get_all(appname, node_id)
+ local balancers = {}
+ local rules = {}
if node then
if server_host and server_port then
node.address = server_host
@@ -682,25 +684,32 @@ function gen_config(var)
end
if is_new_node then
local fallback_node = uci:get_all(appname, fallback_node_id)
- local outbound = gen_outbound(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil })
- if outbound then
- table.insert(outbounds, outbound)
+ if fallback_node.protocol ~= "_balancing" then
+ local outbound = gen_outbound(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil })
+ if outbound then
+ table.insert(outbounds, outbound)
+ else
+ fallback_node_id = nil
+ end
else
- fallback_node_id = nil
+ local valid = gen_balancer(fallback_node)
+ if not valid then
+ fallback_node_id = nil
+ end
end
end
end
- local balancer, rule
+ local valid = nil
if #valid_nodes > 0 then
local balancerTag = get_balancer_tag(_node[".name"])
- balancer = {
+ table.insert(balancers, {
tag = balancerTag,
selector = valid_nodes,
fallbackTag = fallback_node_id,
strategy = { type = _node.balancingStrategy or "random" }
- }
- if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" then
+ })
+ if _node.balancingStrategy == "leastPing" then
if not observatory then
observatory = {
subjectSelector = { "blc-" },
@@ -717,13 +726,10 @@ function gen_config(var)
tag = loopbackTag,
settings = { inboundTag = inboundTag }
})
- rule = {
- type = "field",
- inboundTag = { inboundTag },
- balancerTag = balancerTag
- }
+ table.insert(rules, { type = "field", inboundTag = { inboundTag }, balancerTag = balancerTag })
+ valid = true
end
- return balancer, rule
+ return valid
end
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
@@ -755,9 +761,6 @@ function gen_config(var)
end
if node.protocol == "_shunt" then
- local rules = {}
- local balancers = {}
-
local preproxy_enabled = node.preproxy_enabled == "1"
local preproxy_tag = "main"
local preproxy_node_id = node["main_node"]
@@ -793,11 +796,8 @@ function gen_config(var)
end
elseif preproxy_node and preproxy_node.protocol == "_balancing" then
preproxy_is_balancer = true
- local preproxy_balancer, preproxy_rule = gen_balancer(preproxy_node, preproxy_tag)
- if preproxy_balancer and preproxy_rule then
- table.insert(balancers, preproxy_balancer)
- table.insert(rules, preproxy_rule)
- else
+ local valid = gen_balancer(preproxy_node, preproxy_tag)
+ if not valid then
preproxy_enabled = false
end
end
@@ -913,11 +913,9 @@ function gen_config(var)
end
end
if is_new_balancer then
- local balancer, rule = gen_balancer(_node)
- if balancer then
- table.insert(balancers, balancer)
- table.insert(rules, rule)
- rule_balancerTag = balancer.tag
+ local valid = gen_balancer(_node)
+ if valid then
+ rule_balancerTag = get_balancer_tag(_node_id)
end
end
elseif _node.protocol == "_iface" then
@@ -1043,13 +1041,13 @@ function gen_config(var)
}
elseif node.protocol == "_balancing" then
if node.balancing_node then
- local balancer, rule = gen_balancer(node)
+ local valid = gen_balancer(node)
+ if valid then
+ table.insert(rules, { type = "field", network = "tcp,udp", balancerTag = get_balancer_tag(node_id) })
+ end
routing = {
- balancers = { balancer },
- rules = {
- { type = "field", network = "tcp,udp", balancerTag = balancer.tag },
- rule
- }
+ balancers = balancers,
+ rules = rules
}
end
elseif node.protocol == "_iface" then