diff --git a/applications/luci-app-passwall/Makefile b/applications/luci-app-passwall/Makefile index 43dad41a8cb..f9b2d948cbb 100644 --- a/applications/luci-app-passwall/Makefile +++ b/applications/luci-app-passwall/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall -PKG_VERSION:=25.12.25 +PKG_VERSION:=26.1.1 PKG_RELEASE:=1 PKG_CONFIG_DEPENDS:= \ diff --git a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua index 8be9f271785..177bb1bc214 100644 --- a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua +++ b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua @@ -1,5 +1,5 @@ local api = require "luci.passwall.api" -local appname = "passwall" +local appname = api.appname local datatypes = api.datatypes local net = require "luci.model.network".init() @@ -9,7 +9,8 @@ for k, e in ipairs(api.get_valid_nodes()) do nodes_table[#nodes_table + 1] = { id = e[".name"], obj = e, - remarks = e["remark"] + remarks = e["remark"], + group = e["group"] } end end @@ -17,6 +18,8 @@ end m = Map(appname) api.set_apply_on_parse(m) +m:append(Template(appname .. "/cbi/nodes_value_com")) + -- [[ Haproxy Settings ]]-- s = m:section(TypedSection, "global_haproxy", translate("Basic Settings")) s.anonymous = true @@ -115,10 +118,15 @@ o.rmempty = false ---- Node Address o = s:option(Value, "lbss", translate("Node Address")) -for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end +o.template = appname .. "/cbi/nodes_value" +o.group = {} +for k, v in pairs(nodes_table) do + o:value(v.id, v.remarks) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end o.rmempty = false o.validate = function(self, value) - if not value then return nil end + if not value then return nil, translate("Node address cannot be empty.") end local t = m:get(value) or nil if t and t[".type"] == "nodes" then return value @@ -129,7 +137,7 @@ o.validate = function(self, value) if api.is_ipv6addrport(value) then return value end - return nil, value + return nil, translate("Not valid IP format, please re-enter!") .. " (IP:Port)" end ---- Haproxy Port diff --git a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua index 5b4fa123d3f..160a821871a 100644 --- a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua +++ b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua @@ -730,11 +730,21 @@ o:depends({ [_n("mux")] = true }) o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open")) o.default = 0 +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) --[[tcpMptcp]] o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration.")) o.default = 0 +o = s:option(Value, _n("preconns"), translate("Pre-connections"), translate("Number of early established connections to reduce latency.")) +o.datatype = "uinteger" +o.placeholder = 0 +o:depends({ [_n("protocol")] = "vless" }) + o = s:option(ListValue, _n("chain_proxy"), translate("Chain Proxy")) o:value("", translate("Close(Not use)")) o:value("1", translate("Preproxy Node")) diff --git a/applications/luci-app-passwall/luasrc/passwall/api.lua b/applications/luci-app-passwall/luasrc/passwall/api.lua index 46a1e7b2c3b..fa75dc03829 100644 --- a/applications/luci-app-passwall/luasrc/passwall/api.lua +++ b/applications/luci-app-passwall/luasrc/passwall/api.lua @@ -289,9 +289,9 @@ function url(...) end function trim(s) - local len = #s - local i, j = 1, len - while i <= len and s:byte(i) <= 32 do i = i + 1 end + if type(s) ~= "string" then return "" end + local i, j = 1, #s + while i <= j and s:byte(i) <= 32 do i = i + 1 end while j >= i and s:byte(j) <= 32 do j = j - 1 end if i > j then return "" end return s:sub(i, j) diff --git a/applications/luci-app-passwall/luasrc/passwall/util_xray.lua b/applications/luci-app-passwall/luasrc/passwall/util_xray.lua index d8c932042e2..72cd2f5d168 100644 --- a/applications/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/applications/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -268,6 +268,7 @@ function gen_outbound(flag, node, tag, proxy_table) id = node.uuid, level = 0, security = (node.protocol == "vmess") and node.security or nil, + testpre = (node.protocol == "vless") and tonumber(node.preconns) or nil, encryption = (node.protocol == "vless") and ((node.encryption and node.encryption ~= "") and node.encryption or "none") or nil, flow = (node.protocol == "vless" and (node.tls == "1" or (node.encryption and node.encryption ~= "" and node.encryption ~= "none")) @@ -627,6 +628,7 @@ function gen_config(var) local dns = nil local fakedns = nil local routing = nil + local observatory = nil local burstObservatory = nil local strategy = nil local inbounds = {} @@ -867,18 +869,23 @@ function gen_config(var) fallbackTag = fallback_node_tag, strategy = strategy }) - if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" or fallback_node_tag then - if not burstObservatory then - burstObservatory = { - subjectSelector = { "blc-" }, - pingConfig = { - destination = _node.useCustomProbeUrl and _node.probeUrl or nil, - interval = (api.format_go_time(_node.probeInterval) ~= "0s") and api.format_go_time(_node.probeInterval) or "1m", - sampling = 3, - timeout = "5s" - } + if _node.balancingStrategy == "leastPing" and not observatory then + observatory = { + subjectSelector = { "blc-" }, + probeUrl = _node.useCustomProbeUrl and _node.probeUrl or nil, + probeInterval = (api.format_go_time(_node.probeInterval) ~= "0s") and api.format_go_time(_node.probeInterval) or "1m", + enableConcurrency = true + } + elseif _node.balancingStrategy == "leastLoad" and not burstObservatory then + burstObservatory = { + subjectSelector = { "blc-" }, + pingConfig = { + destination = _node.useCustomProbeUrl and _node.probeUrl or nil, + interval = (api.format_go_time(_node.probeInterval) ~= "0s") and api.format_go_time(_node.probeInterval) or "1m", + sampling = 3, + timeout = "5s" } - end + } end local inbound_tag = gen_loopback(loopback_tag, loopback_dst) table.insert(rules, { inboundTag = { inbound_tag }, balancerTag = balancer_tag }) @@ -1397,7 +1404,7 @@ function gen_config(var) address = remote_dns_udp_server or remote_dns_tcp_server, port = tonumber(remote_dns_udp_port) or tonumber(remote_dns_tcp_port), network = remote_dns_udp_server and "udp" or "tcp", - nonIPQuery = "drop" + nonIPQuery = "reject" } }) @@ -1514,6 +1521,7 @@ function gen_config(var) -- 传出连接 outbounds = outbounds, -- 连接观测 + observatory = (not burstObservatory) and observatory or nil, burstObservatory = burstObservatory, -- 路由 routing = routing, diff --git a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm index 1bcf0ab744f..2081a531b90 100644 --- a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm +++ b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm @@ -104,7 +104,7 @@