diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua
index 2e84e907b..7e7ded1e6 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua
@@ -18,6 +18,83 @@ protocol:value("http")
protocol:value("tls")
protocol:value("bittorrent")
+network = s:option(ListValue, "network", translate("Network"))
+network:value("tcp,udp", "TCP UDP")
+network:value("tcp", "TCP")
+network:value("udp", "UDP")
+
+source = s:option(DynamicList, "source", translate("Source"))
+source.description = "
- " .. translate("Example:")
+.. "
- " .. translate("IP") .. ": 192.168.1.100"
+.. "
- " .. translate("IP CIDR") .. ": 192.168.1.0/24"
+.. "
- " .. translate("GeoIP") .. ": geoip:private"
+.. "
"
+source.cast = "string"
+source.cfgvalue = function(self, section)
+ local value
+ if self.tag_error[section] then
+ value = self:formvalue(section)
+ else
+ value = self.map:get(section, self.option)
+ if type(value) == "string" then
+ local value2 = {}
+ string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end)
+ value = value2
+ end
+ end
+ return value
+end
+source.validate = function(self, value, t)
+ local err = {}
+ for _, v in ipairs(value) do
+ local flag = false
+ if datatypes.ip4addr(v) then
+ flag = true
+ end
+
+ if flag == false and v:find("geoip:") and v:find("geoip:") == 1 then
+ flag = true
+ end
+
+ if flag == false then
+ err[#err + 1] = v
+ end
+ end
+
+ if #err > 0 then
+ self:add_error(t, "invalid", translate("Not true format, please re-enter!"))
+ for _, v in ipairs(err) do
+ self:add_error(t, "invalid", v)
+ end
+ end
+
+ return value
+end
+
+local dynamicList_write = function(self, section, value)
+ local t = {}
+ local t2 = {}
+ if type(value) == "table" then
+ local x
+ for _, x in ipairs(value) do
+ if x and #x > 0 then
+ if not t2[x] then
+ t2[x] = x
+ t[#t+1] = x
+ end
+ end
+ end
+ else
+ t = { value }
+ end
+ t = table.concat(t, " ")
+ return DynamicList.write(self, section, t)
+end
+
+source.write = dynamicList_write
+
+port = s:option(Value, "port", translate("port"))
+
domain_list = s:option(TextValue, "domain_list", translate("Domain"))
domain_list.rows = 10
domain_list.wrap = "off"
diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua
index b98cd94f3..f0b7d8885 100644
--- a/luci-app-passwall/luasrc/passwall/util_xray.lua
+++ b/luci-app-passwall/luasrc/passwall/util_xray.lua
@@ -870,39 +870,52 @@ function gen_config(var)
table.insert(protocols, w)
end)
end
+ local domains = nil
if e.domain_list then
- local _domain = {}
+ domains = {}
string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w)
- table.insert(_domain, w)
+ table.insert(domains, w)
end)
- table.insert(rules, {
- type = "field",
- outboundTag = outboundTag,
- balancerTag = balancerTag,
- domain = _domain,
- protocol = protocols
- })
end
+ local ip = nil
if e.ip_list then
- local _ip = {}
+ ip = {}
string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w)
- table.insert(_ip, w)
+ table.insert(ip, w)
end)
- table.insert(rules, {
- type = "field",
- outboundTag = outboundTag,
- balancerTag = balancerTag,
- ip = _ip,
- protocol = protocols
- })
end
- if not e.domain_list and not e.ip_list and protocols then
- table.insert(rules, {
- type = "field",
- outboundTag = outboundTag,
- balancerTag = balancerTag,
- protocol = protocols
- })
+ local source = nil
+ if e.source then
+ source = {}
+ string.gsub(e.source, '[^' .. " " .. ']+', function(w)
+ table.insert(source, w)
+ end)
+ end
+ local rule = {
+ _flag = e.remarks,
+ type = "field",
+ outboundTag = outboundTag,
+ balancerTag = balancerTag,
+ network = e["network"] or "tcp,udp",
+ source = source,
+ sourcePort = nil,
+ port = e["port"] ~= "" and e["port"] or nil,
+ protocol = protocols
+ }
+ if domains then
+ local _rule = api.clone(rule)
+ _rule["_flag"] = _rule["_flag"] .. "_domains"
+ _rule.domains = domains
+ table.insert(rules, _rule)
+ end
+ if ip then
+ local _rule = api.clone(rule)
+ _rule["_flag"] = _rule["_flag"] .. "_ip"
+ _rule.ip = ip
+ table.insert(rules, _rule)
+ end
+ if not domains and not ip and protocols then
+ table.insert(rules, rule)
end
end
end)