From 86ca0a6e5aa341be228773e636b5fd43f24eabcc Mon Sep 17 00:00:00 2001 From: xiaorouji <60100640+xiaorouji@users.noreply.github.com> Date: Mon, 26 Feb 2024 21:16:40 +0800 Subject: [PATCH] luci: add Xray node a layer chain proxy logic Can set it in the node configuration, no need to use shunt mode. --- .../model/cbi/passwall/client/type/ray.lua | 20 +++++- .../luasrc/passwall/util_xray.lua | 67 ++++++++++++++----- 2 files changed, 68 insertions(+), 19 deletions(-) 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 7d113d768..d0055a11a 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 @@ -54,7 +54,8 @@ for k, e in ipairs(api.get_valid_nodes()) do if e.node_type == "normal" then nodes_table[#nodes_table + 1] = { id = e[".name"], - remarks = e["remark"] + remarks = e["remark"], + type = e["type"] } end if e.protocol == "_balancing" then @@ -522,4 +523,21 @@ o.default = 0 o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay") o.default = 0 +o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy.")) +o.default = "" +o:value("", translate("Close(Not use)")) +for k, v in pairs(nodes_table) do + if v.type == "Xray" then + o:value(v.id, v.remarks) + end +end + +for i, v in ipairs(s.fields[option_name("protocol")].keylist) do + if not v:find("_") then + s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v }) + s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v }) + s.fields[option_name("to_node")]:depends({ [option_name("protocol")] = v }) + end +end + api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua index a13c9ed15..04c6b03fc 100644 --- a/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -697,6 +697,34 @@ function gen_config(var) return balancer, rule end + local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name) + if not node or not outbound or not outbounds_table then return nil end + local default_outTag = outbound.tag + + if node.to_node then + local to_node = uci:get_all(appname, node.to_node) + if to_node then + local to_outbound = gen_outbound(nil, to_node) + if to_outbound then + if shunt_rule_name then + to_outbound.tag = outbound.tag + outbound.tag = node[".name"] + else + to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag + end + + to_outbound.proxySettings = { + tag = outbound.tag, + transportLayer = true + } + table.insert(outbounds_table, to_outbound) + default_outTag = to_outbound.tag + end + end + end + return default_outTag + end + if node.protocol == "_shunt" then local rules = {} local balancers = {} @@ -728,6 +756,7 @@ function gen_config(var) elseif preproxy_node and api.is_normal_node(preproxy_node) then local preproxy_outbound = gen_outbound(flag, preproxy_node, preproxy_tag, { fragment = xray_settings.fragment == "1" or nil }) if preproxy_outbound then + set_outbound_detour(preproxy_node, preproxy_outbound, outbounds, preproxy_tag) table.insert(outbounds, preproxy_outbound) else preproxy_enabled = false @@ -743,7 +772,7 @@ function gen_config(var) end end - local function gen_shunt_node(rule_name, _node_id, as_proxy) + local function gen_shunt_node(rule_name, _node_id) if not rule_name then return nil, nil end if not _node_id then _node_id = node[rule_name] or "nil" end local rule_outboundTag @@ -837,6 +866,7 @@ function gen_config(var) end local _outbound = gen_outbound(flag, _node, rule_name, proxy_table) if _outbound then + set_outbound_detour(_node, _outbound, outbounds, rule_name) table.insert(outbounds, _outbound) if proxy then preproxy_used = true end rule_outboundTag = rule_name @@ -989,26 +1019,27 @@ function gen_config(var) } } end - else - local outbound = nil - if node.protocol == "_iface" then - if node.iface then - outbound = { - protocol = "freedom", - tag = "outbound", - streamSettings = { - sockopt = { - mark = 255, - interface = node.iface - } + elseif node.protocol == "_iface" then + if node.iface then + local outbound = { + protocol = "freedom", + tag = "outbound", + streamSettings = { + sockopt = { + mark = 255, + interface = node.iface } } - sys.call("touch /tmp/etc/passwall/iface/" .. node.iface) - end - else - outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil }) + } + table.insert(outbounds, outbound) + sys.call("touch /tmp/etc/passwall/iface/" .. node.iface) + end + else + local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil }) + if outbound then + set_outbound_detour(node, outbound, outbounds) + table.insert(outbounds, outbound) end - if outbound then table.insert(outbounds, outbound) end routing = { domainStrategy = "AsIs", domainMatcher = "hybrid",