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 65c67da40..d6186976f 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 @@ -65,13 +65,13 @@ o.default = "eth1" o:depends({ [option_name("protocol")] = "_iface" }) local nodes_table = {} -local balancers_table = {} local iface_table = {} 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 == "_iface" then @@ -89,9 +89,6 @@ if #nodes_table > 0 then o = s:option(Value, option_name("main_node"), string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not.")) o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true }) - for k, v in pairs(balancers_table) do - o:value(v.id, v.remarks) - end for k, v in pairs(iface_table) do o:value(v.id, v.remarks) end @@ -110,9 +107,6 @@ uci:foreach(appname, "shunt_rules", function(e) o:depends({ [option_name("protocol")] = "_shunt" }) if #nodes_table > 0 then - for k, v in pairs(balancers_table) do - o:value(v.id, v.remarks) - end for k, v in pairs(iface_table) do o:value(v.id, v.remarks) end @@ -142,9 +136,6 @@ o:value("_direct", translate("Direct Connection")) o:value("_blackhole", translate("Blackhole")) if #nodes_table > 0 then - for k, v in pairs(balancers_table) do - o:value(v.id, v.remarks) - end for k, v in pairs(iface_table) do o:value(v.id, v.remarks) end @@ -631,4 +622,18 @@ o:value("prefer_ipv6") o:value("ipv4_only") o:value("ipv6_only") +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 == "sing-box" 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 + o: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_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua index e7b57c018..a659a910a 100644 --- a/luci-app-passwall/luasrc/passwall/util_sing-box.lua +++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua @@ -875,6 +875,53 @@ function gen_config(var) table.insert(inbounds, inbound) 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.shadowtls == "1" then + local _node = { + type = "sing-box", + protocol = "shadowtls", + shadowtls_version = node.shadowtls_version, + password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil, + address = node.address, + port = node.port, + tls = "1", + tls_serverName = node.shadowtls_serverName, + utls = node.shadowtls_utls, + fingerprint = node.shadowtls_fingerprint + } + local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls") + if shadowtls_outbound then + table.insert(outbounds_table, shadowtls_outbound) + outbound.detour = outbound.tag .. "_shadowtls" + outbound.server = nil + outbound.server_port = nil + end + end + + 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.detour = outbound.tag + 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 = {} @@ -903,34 +950,14 @@ 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) if preproxy_outbound then - if preproxy_node.shadowtls == "1" then - local _node = { - type = "sing-box", - protocol = "shadowtls", - shadowtls_version = preproxy_node.shadowtls_version, - password = (preproxy_node.shadowtls_version == "2" or preproxy_node.shadowtls_version == "3") and preproxy_node.shadowtls_password or nil, - address = preproxy_node.address, - port = preproxy_node.port, - tls = "1", - tls_serverName = preproxy_node.shadowtls_serverName, - utls = preproxy_node.shadowtls_utls, - fingerprint = preproxy_node.shadowtls_fingerprint - } - local shadowtls_outbound = gen_outbound(flag, _node, preproxy_tag .. "_shadowtls") - if shadowtls_outbound then - table.insert(outbounds, shadowtls_outbound) - preproxy_outbound.detour = preproxy_outbound.tag .. "_shadowtls" - preproxy_outbound.server = nil - preproxy_outbound.server_port = nil - end - end + set_outbound_detour(preproxy_node, preproxy_outbound, outbounds, preproxy_tag) table.insert(outbounds, preproxy_outbound) else preproxy_enabled = false 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 @@ -1002,27 +1029,7 @@ function gen_config(var) end local _outbound = gen_outbound(flag, _node, rule_name, { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil }) if _outbound then - if _node.shadowtls == "1" then - local shadowtls_node = { - type = "sing-box", - protocol = "shadowtls", - shadowtls_version = _node.shadowtls_version, - password = (_node.shadowtls_version == "2" or _node.shadowtls_version == "3") and _node.shadowtls_password or nil, - address = _node.address, - port = _node.port, - tls = "1", - tls_serverName = _node.shadowtls_serverName, - utls = _node.shadowtls_utls, - fingerprint = _node.shadowtls_fingerprint - } - local shadowtls_outbound = gen_outbound(flag, shadowtls_node, rule_name .. "_shadowtls", { proxy = proxy and 1 or 0, tag = proxy and preproxy_tag or nil }) - if shadowtls_outbound then - table.insert(outbounds, shadowtls_outbound) - _outbound.detour = _outbound.tag .. "_shadowtls" - _outbound.server = nil - _outbound.server_port = nil - end - end + set_outbound_detour(_node, _outbound, outbounds, rule_name) table.insert(outbounds, _outbound) rule_outboundTag = rule_name end @@ -1201,46 +1208,23 @@ function gen_config(var) for index, value in ipairs(rules) do table.insert(route.rules, rules[index]) end - else - local outbound = nil - if node.protocol == "_iface" then - if node.iface then - outbound = { - type = "direct", - tag = node_id, - bind_interface = node.iface, - routing_mark = 255, - } - sys.call("touch /tmp/etc/passwall/iface/" .. node.iface) - end - else - outbound = gen_outbound(flag, node) - if outbound then - if node.shadowtls == "1" then - local shadowtls_node = { - type = "sing-box", - protocol = "shadowtls", - shadowtls_version = node.shadowtls_version, - password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil, - address = node.address, - port = node.port, - tls = "1", - tls_serverName = node.shadowtls_serverName, - utls = node.shadowtls_utls, - fingerprint = node.shadowtls_fingerprint - } - local shadowtls_outbound = gen_outbound(flag, shadowtls_node, outbound.tag .. "_shadowtls") - if shadowtls_outbound then - table.insert(outbounds, shadowtls_outbound) - outbound.detour = outbound.tag .. "_shadowtls" - outbound.server = nil - outbound.server_port = nil - end - end - end - end - if outbound then + elseif node.protocol == "_iface" then + if node.iface then + local outbound = { + type = "direct", + tag = node_id, + bind_interface = node.iface, + routing_mark = 255, + } + table.insert(outbounds, outbound) default_outTag = outbound.tag + route.final = default_outTag + sys.call("touch /tmp/etc/passwall/iface/" .. node.iface) + end + else + local outbound = gen_outbound(flag, node) + if outbound then + default_outTag = set_outbound_detour(node, outbound, outbounds) table.insert(outbounds, outbound) route.final = default_outTag end diff --git a/luci-app-passwall/po/zh-cn/passwall.po b/luci-app-passwall/po/zh-cn/passwall.po index 5286a2da1..69f99ed12 100644 --- a/luci-app-passwall/po/zh-cn/passwall.po +++ b/luci-app-passwall/po/zh-cn/passwall.po @@ -1569,3 +1569,9 @@ msgstr "分片间隔(ms)" msgid "If is domain name, The requested domain name will be resolved to IP before connect." msgstr "如果是域名,域名将在请求发出之前解析为 IP。" + +msgid "Landing node" +msgstr "落地节点" + +msgid "Only support a layer of proxy." +msgstr "仅支持一层代理。"