diff options
4 files changed, 146 insertions, 79 deletions
diff --git a/applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev/rules.lua b/applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev/rules.lua index 9985790174..4a01bed247 100644 --- a/applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev/rules.lua +++ b/applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev/rules.lua @@ -9,23 +9,28 @@ m = Map("shadowsocks-libev", translate("Redir Rules"), translate("On this page you can configure how traffics are to be \ forwarded to ss-redir instances. \ - If enabled, packets will first have their source ip addresses checked \ - against <em>Src ip bypass</em>, <em>Src ip forward</em>, \ - <em>Src ip checkdst</em> and if none matches <em>Src default</em> \ + If enabled, packets will first have their src ip addresses checked \ + against <em>Src ip/net bypass</em>, <em>Src ip/net forward</em>, \ + <em>Src ip/net checkdst</em> and if none matches <em>Src default</em> \ will give the default action to be taken. \ If the prior check results in action <em>checkdst</em>, packets will continue \ - to have their destination addresses checked.")) + to have their dst addresses checked.")) local sdata = m:get('ss_rules') if not sdata then m:set('ss_rules', nil, 'ss_rules') - m:set('ss_rules', 'disabled', true) + m:set('ss_rules', 'disabled', "1") +end + +function src_dst_option(s, ...) + local o = s:taboption(...) + o.datatype = "or(ip4addr,cidr4)" end s = m:section(NamedSection, "ss_rules", "ss_rules") s:tab("general", translate("General Settings")) -s:tab("srcip", translate("Source Settings")) -s:tab("dstip", translate("Destination Settings")) +s:tab("src", translate("Source Settings")) +s:tab("dst", translate("Destination Settings")) s:taboption('general', Flag, "disabled", translate("Disable")) ss.option_install_package(s, 'general') @@ -49,38 +54,56 @@ s:taboption('general', Value, "ipt_args", translate("Extra arguments"), translate("Passes additional arguments to iptables. Use with care!")) -s:taboption('srcip', DynamicList, "src_ips_bypass", - translate("Src ip bypass"), - translate("Bypass redir action for packets with source addresses in this list")) -s:taboption('srcip', DynamicList, "src_ips_forward", - translate("Src ip forward"), - translate("Go through redir action for packets with source addresses in this list")) -s:taboption('srcip', DynamicList, "src_ips_checkdst", - translate("Src ip checkdst"), - translate("Continue to have dst address checked for packets with source addresses in this list")) -o = s:taboption('srcip', ListValue, "src_default", +src_dst_option(s, 'src', DynamicList, "src_ips_bypass", + translate("Src ip/net bypass"), + translate("Bypass ss-redir for packets with src address in this list")) +src_dst_option(s, 'src', DynamicList, "src_ips_forward", + translate("Src ip/net forward"), + translate("Forward through ss-redir for packets with src address in this list")) +src_dst_option(s, 'src', DynamicList, "src_ips_checkdst", + translate("Src ip/net checkdst"), + translate("Continue to have dst address checked for packets with src address in this list")) +o = s:taboption('src', ListValue, "src_default", translate("Src default"), - translate("Default action for packets whose source addresses do not match any of the source ip list")) + translate("Default action for packets whose src address do not match any of the src ip/net list")) ss.values_actions(o) -s:taboption('dstip', DynamicList, "dst_ips_bypass", - translate("Dst ip bypass"), - translate("Bypass redir action for packets with destination addresses in this list")) -s:taboption('dstip', DynamicList, "dst_ips_forward", - translate("Dst ip forward"), - translate("Go through redir action for packets with destination addresses in this list")) +src_dst_option(s, 'dst', DynamicList, "dst_ips_bypass", + translate("Dst ip/net bypass"), + translate("Bypass ss-redir for packets with dst address in this list")) +src_dst_option(s, 'dst', DynamicList, "dst_ips_forward", + translate("Dst ip/net forward"), + translate("Forward through ss-redir for packets with dst address in this list")) -o = s:taboption('dstip', FileBrowser, "dst_ips_bypass_file", - translate("Dst ip bypass file"), - translate("File containing ip addresses for the purposes as with <em>Dst ip bypass</em>")) +o = s:taboption('dst', FileBrowser, "dst_ips_bypass_file", + translate("Dst ip/net bypass file"), + translate("File containing ip/net for the purposes as with <em>Dst ip/net bypass</em>")) o.datatype = "file" -s:taboption('dstip', FileBrowser, "dst_ips_forward_file", - translate("Dst ip forward file"), - translate("File containing ip addresses for the purposes as with <em>Dst ip forward</em>")) +s:taboption('dst', FileBrowser, "dst_ips_forward_file", + translate("Dst ip/net forward file"), + translate("File containing ip/net for the purposes as with <em>Dst ip/net forward</em>")) o.datatype = "file" -o = s:taboption('dstip', ListValue, "dst_default", +o = s:taboption('dst', ListValue, "dst_default", translate("Dst default"), - translate("Default action for packets whose destination addresses do not match any of the destination ip list")) + translate("Default action for packets whose dst address do not match any of the dst ip list")) ss.values_actions(o) +local installed = os.execute("iptables -m recent -h &>/dev/null") == 0 +if installed then + o = s:taboption('dst', Flag, "dst_forward_recentrst") +else + m:set('ss_rules', 'dst_forward_recentrst', "0") + o = s:taboption("dst", Button, "_install") + o.inputtitle = translate("Install package iptables-mod-conntrack-extra") + o.inputstyle = "apply" + o.write = function() + return luci.http.redirect( + luci.dispatcher.build_url("admin/system/packages") .. + "?submit=1&install=iptables-mod-conntrack-extra" + ) + end +end +o.title = translate("Forward recentrst") +o.description = translate("Forward those packets whose dst have recently sent to us multiple tcp-rst") + return m diff --git a/applications/luci-app-shadowsocks-libev/luasrc/model/shadowsocks-libev.lua b/applications/luci-app-shadowsocks-libev/luasrc/model/shadowsocks-libev.lua index 650ff6356e..7ba6b40c53 100644 --- a/applications/luci-app-shadowsocks-libev/luasrc/model/shadowsocks-libev.lua +++ b/applications/luci-app-shadowsocks-libev/luasrc/model/shadowsocks-libev.lua @@ -3,6 +3,7 @@ local _up = getfenv(3) local ut = require("luci.util") +local sys = require("luci.sys") local ds = require("luci.dispatcher") local nw = require("luci.model.network") nw.init() @@ -23,13 +24,16 @@ end function values_redir(o, xmode) o.map.uci.foreach("shadowsocks-libev", "ss_redir", function(sdata) + local disabled = ucival_to_bool(sdata["disabled"]) local sname = sdata[".name"] local mode = sdata["mode"] or "tcp_only" - if mode and mode:find(xmode) then + if not disabled and mode:find(xmode) then local desc = "%s - %s" % {sname, mode} o:value(sname, desc) end end) + o:value("", "<unset>") + o.default = "" end function values_serverlist(o) @@ -53,10 +57,8 @@ function values_ipaddr(o) end function values_ifnames(o) - for _, v in ipairs(nw:get_interfaces()) do - if v.dev then - o:value(v.dev.name) - end + for _, v in ipairs(sys.net.devices()) do + o:value(v) end end diff --git a/modules/luci-base/htdocs/luci-static/resources/cbi.js b/modules/luci-base/htdocs/luci-static/resources/cbi.js index b819230cf3..884eb62f68 100644 --- a/modules/luci-base/htdocs/luci-static/resources/cbi.js +++ b/modules/luci-base/htdocs/luci-static/resources/cbi.js @@ -118,48 +118,88 @@ var cbi_validators = { return false; }, - 'ipmask': function() + 'ip4prefix': function() { - return cbi_validators.ipmask4.apply(this) || - cbi_validators.ipmask6.apply(this); + return !isNaN(this) && this >= 0 && this <= 32; }, - 'ipmask4': function() + 'ip6prefix': function() { - var ip = this, mask = 32; + return !isNaN(this) && this >= 0 && this <= 128; + }, - if (ip.match(/^(\S+)\/(\S+)$/)) + 'cidr': function() + { + return cbi_validators.cidr4.apply(this) || + cbi_validators.cidr6.apply(this); + }, + + 'cidr4': function() + { + if (this.match(/^(\S+)\/(\S+)$/)) { ip = RegExp.$1; mask = RegExp.$2; + return cbi_validators.ip4addr.apply(ip) && + cbi_validators.ip4prefix.apply(mask); } + return false; + }, - if (!isNaN(mask) && (mask < 0 || mask > 32)) - return false; - - if (isNaN(mask) && !cbi_validators.ip4addr.apply(mask)) - return false; - - return cbi_validators.ip4addr.apply(ip); + 'cidr6': function() + { + if (this.match(/^(\S+)\/(\S+)$/)) + { + ip = RegExp.$1; + mask = RegExp.$2; + return cbi_validators.ip6addr.apply(ip) && + cbi_validators.ip6prefix.apply(mask); + } + return false; }, - 'ipmask6': function() + 'ipnet4': function() { - var ip = this, mask = 128; + if (this.match(/^(\S+)\/(\S+)$/)) + { + ip = RegExp.$1; + net = RegExp.$2; + return cbi_validators.ip4addr.apply(ip) && + cbi_validators.ip4addr.apply(net); + } + return false; + }, - if (ip.match(/^(\S+)\/(\S+)$/)) + 'ipnet6': function() + { + if (this.match(/^(\S+)\/(\S+)$/)) { ip = RegExp.$1; - mask = RegExp.$2; + net = RegExp.$2; + return cbi_validators.ip6addr.apply(ip) && + cbi_validators.ip6addr.apply(net); } + return false; + }, - if (!isNaN(mask) && (mask < 0 || mask > 128)) - return false; + 'ipmask': function() + { + return cbi_validators.ipmask4.apply(this) || + cbi_validators.ipmask6.apply(this); + }, - if (isNaN(mask) && !cbi_validators.ip6addr.apply(mask)) - return false; + 'ipmask4': function() + { + return cbi_validators.cidr4.apply(this) || + cbi_validators.ipnet4.apply(this) || + cbi_validators.ip4addr.apply(this); + }, - return cbi_validators.ip6addr.apply(ip); + 'ipmask6': function() + { + return cbi_validators.cidr6.apply(this) || + cbi_validators.ipnet6.apply(this) || + cbi_validators.ip6addr.apply(this); }, 'port': function() diff --git a/modules/luci-base/luasrc/cbi/datatypes.lua b/modules/luci-base/luasrc/cbi/datatypes.lua index cf56566287..df23aaf135 100644 --- a/modules/luci-base/luasrc/cbi/datatypes.lua +++ b/modules/luci-base/luasrc/cbi/datatypes.lua @@ -132,38 +132,40 @@ function ip6prefix(val) return ( val and val >= 0 and val <= 128 ) end -function ipmask(val) - return ipmask4(val) or ipmask6(val) +function cidr4(val) + local ip, mask = val:match("^([^/]+)/([^/]+)$") + + return ip4addr(ip) and ip4prefix(mask) end -function ipmask4(val) +function cidr6(val) local ip, mask = val:match("^([^/]+)/([^/]+)$") - local bits = tonumber(mask) - if bits and (bits < 0 or bits > 32) then - return false - end + return ip6addr(ip) and ip6prefix(mask) +end - if not bits and mask and not ip4addr(mask) then - return false - end +function ipnet4(val) + local ip, mask = val:match("^([^/]+)/([^/]+)$") - return ip4addr(ip or val) + return ip4addr(ip) and ip4addr(mask) end -function ipmask6(val) +function ipnet6(val) local ip, mask = val:match("^([^/]+)/([^/]+)$") - local bits = tonumber(mask) - if bits and (bits < 0 or bits > 128) then - return false - end + return ip6addr(ip) and ip6addr(mask) +end - if not bits and mask and not ip6addr(mask) then - return false - end +function ipmask(val) + return ipmask4(val) or ipmask6(val) +end + +function ipmask4(val) + return cidr4(val) or ipnet4(val) or ip4addr(val) +end - return ip6addr(ip or val) +function ipmask6(val) + return cidr6(val) or ipnet6(val) or ip6addr(val) end function ip6hostid(val) |