diff --git a/package/lienol/luci-app-passwall/Makefile b/package/lienol/luci-app-passwall/Makefile
index d1c0bff709..2ed8b8df84 100644
--- a/package/lienol/luci-app-passwall/Makefile
+++ b/package/lienol/luci-app-passwall/Makefile
@@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=3.9
-PKG_RELEASE:=37
-PKG_DATE:=20200813
+PKG_RELEASE:=38
+PKG_DATE:=20200817
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
diff --git a/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua b/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua
index 0a141d2b50..8bfb0453a4 100644
--- a/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua
@@ -21,20 +21,22 @@ function index()
entry({"admin", "services", appname, "settings"}, cbi("passwall/global"), _("Basic Settings"), 1).dependent = true
entry({"admin", "services", appname, "node_list"}, cbi("passwall/node_list"), _("Node List"), 2).dependent = true
entry({"admin", "services", appname, "auto_switch"}, cbi("passwall/auto_switch"), _("Auto Switch"), 3).leaf = true
- entry({"admin", "services", appname, "other"}, cbi("passwall/other", {autoapply = true}), _("Other Settings"), 93).leaf = true
+ entry({"admin", "services", appname, "other"}, cbi("passwall/other", {autoapply = true}), _("Other Settings"), 92).leaf = true
if nixio.fs.access("/usr/sbin/haproxy") then
- entry({"admin", "services", appname, "haproxy"}, cbi("passwall/haproxy"), _("Load Balancing"), 94).leaf = true
+ entry({"admin", "services", appname, "haproxy"}, cbi("passwall/haproxy"), _("Load Balancing"), 93).leaf = true
end
- entry({"admin", "services", appname, "node_subscribe"}, cbi("passwall/node_subscribe"), _("Node Subscribe"), 95).dependent = true
+ entry({"admin", "services", appname, "node_subscribe"}, cbi("passwall/node_subscribe"), _("Node Subscribe"), 94).dependent = true
+ entry({"admin", "services", appname, "app_update"}, cbi("passwall/app_update"), _("App Update"), 95).leaf = true
entry({"admin", "services", appname, "rule"}, cbi("passwall/rule"), _("Rule Manage"), 96).leaf = true
- entry({"admin", "services", appname, "app_update"}, cbi("passwall/app_update"), _("App Update"), 97).leaf = true
+ entry({"admin", "services", appname, "rule_list"}, cbi("passwall/rule_list"), _("Rule List Manage"), 97).leaf = true
entry({"admin", "services", appname, "node_config"}, cbi("passwall/node_config")).leaf = true
entry({"admin", "services", appname, "shunt_rules"}, cbi("passwall/shunt_rules")).leaf = true
entry({"admin", "services", appname, "acl"}, cbi("passwall/acl"), _("Access control"), 98).leaf = true
- entry({"admin", "services", appname, "log"}, form("passwall/log"), _("Watch Logs"), 999).leaf = true
entry({"admin", "services", appname, "server"}, cbi("passwall/server/index"), _("Server-Side"), 99).leaf = true
+ entry({"admin", "services", appname, "log"}, form("passwall/log"), _("Watch Logs"), 999).leaf = true
entry({"admin", "services", appname, "server_user"}, cbi("passwall/server/user")).leaf = true
+ --[[ API ]]
entry({"admin", "services", appname, "server_user_status"}, call("server_user_status")).leaf = true
entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true
entry({"admin", "services", appname, "server_clear_log"}, call("server_clear_log")).leaf = true
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/acl.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/acl.lua
index 969eceb747..09fb8aea50 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/acl.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/acl.lua
@@ -1,60 +1,8 @@
local sys = require "luci.sys"
-local fs = require "nixio.fs"
local appname = "passwall"
m = Map(appname)
--- [[ Rule List Settings ]]--
-s = m:section(TypedSection, "global_rules")
-s.anonymous = true
-
-s:tab("direct_list", translate("Direct List"))
-s:tab("proxy_list", translate("Proxy List"))
-
----- Direct Hosts
-local direct_host = string.format("/usr/share/%s/rules/direct_host", appname)
-o = s:taboption("direct_list", TextValue, "direct_hosts", "", "" .. translate("Join the direct hosts list of domain names will not proxy.") .. "")
-o.rows = 8
-o.wrap = "off"
-o.cfgvalue = function(self, section) return fs.readfile(direct_host) or "" end
-o.write = function(self, section, value)
- fs.writefile(direct_host, value:gsub("\r\n", "\n"):gsub("https://", ""):gsub("http://", ""))
-end
-o.remove = function(self, section, value) fs.writefile(direct_host, "") end
-
----- Direct IP
-local direct_ip = string.format("/usr/share/%s/rules/direct_ip", appname)
-o = s:taboption("direct_list", TextValue, "direct_ip", "", "" .. translate("These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5.") .. "")
-o.rows = 8
-o.wrap = "off"
-o.cfgvalue = function(self, section) return fs.readfile(direct_ip) or "" end
-o.write = function(self, section, value)
- fs.writefile(direct_ip, value:gsub("\r\n", "\n"):gsub("https://", ""):gsub("http://", ""))
-end
-o.remove = function(self, section, value) fs.writefile(direct_ip, "") end
-
----- Proxy Hosts
-local proxy_host = string.format("/usr/share/%s/rules/proxy_host", appname)
-o = s:taboption("proxy_list", TextValue, "proxy_host", "", "" .. translate("These had been joined websites will use proxy. Please input the domain names of websites,every line can input only one website domain. For example: google.com.") .. "")
-o.rows = 8
-o.wrap = "off"
-o.cfgvalue = function(self, section) return fs.readfile(proxy_host) or "" end
-o.write = function(self, section, value)
- fs.writefile(proxy_host, value:gsub("\r\n", "\n"):gsub("https://", ""):gsub("http://", ""))
-end
-o.remove = function(self, section, value) fs.writefile(proxy_host, "") end
-
----- Proxy IP
-local proxy_ip = string.format("/usr/share/%s/rules/proxy_ip", appname)
-o = s:taboption("proxy_list", TextValue, "blacklist_ip", "", "" .. translate("These had been joined ip addresses will use proxy.Please input the ip address or ip address segment,every line can input only one ip address.For example: 35.24.0.0/24 or 8.8.4.4.") .. "")
-o.rows = 8
-o.wrap = "off"
-o.cfgvalue = function(self, section) return fs.readfile(proxy_ip) or "" end
-o.write = function(self, section, value)
- fs.writefile(proxy_ip, value:gsub("\r\n", "\n"):gsub("https://", ""):gsub("http://", ""))
-end
-o.remove = function(self, section, value) fs.writefile(proxy_ip, "") end
-
-- [[ ACLs Settings ]]--
s = m:section(TypedSection, "acl_rule", translate("ACLs"), "" .. translate("ACLs is a tools which used to designate specific IP proxy mode, IP or MAC address can be entered.") .. "")
s.template = "cbi/tblsection"
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/rule_list.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/rule_list.lua
new file mode 100644
index 0000000000..954670a1f2
--- /dev/null
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/rule_list.lua
@@ -0,0 +1,89 @@
+local fs = require "nixio.fs"
+local appname = "passwall"
+
+m = Map(appname)
+
+-- [[ Rule List Settings ]]--
+s = m:section(TypedSection, "global_rules")
+s.anonymous = true
+
+s:tab("direct_list", translate("Direct List"))
+s:tab("proxy_list", translate("Proxy List"))
+
+---- Direct Hosts
+local direct_host = string.format("/usr/share/%s/rules/direct_host", appname)
+o = s:taboption("direct_list", TextValue, "direct_hosts", "", "" .. translate("Join the direct hosts list of domain names will not proxy.") .. "")
+o.rows = 15
+o.wrap = "off"
+o.cfgvalue = function(self, section) return fs.readfile(direct_host) or "" end
+o.write = function(self, section, value) fs.writefile(direct_host, value:gsub("\r\n", "\n")) end
+o.remove = function(self, section, value) fs.writefile(direct_host, "") end
+o.validate = function(self, value)
+ local hosts= {}
+ string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
+ for index, host in ipairs(hosts) do
+ if not datatypes.hostname(host) then
+ return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
+ end
+ end
+ return value
+end
+
+---- Direct IP
+local direct_ip = string.format("/usr/share/%s/rules/direct_ip", appname)
+o = s:taboption("direct_list", TextValue, "direct_ip", "", "" .. translate("These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5.") .. "")
+o.rows = 15
+o.wrap = "off"
+o.cfgvalue = function(self, section) return fs.readfile(direct_ip) or "" end
+o.write = function(self, section, value) fs.writefile(direct_ip, value:gsub("\r\n", "\n")) end
+o.remove = function(self, section, value) fs.writefile(direct_ip, "") end
+o.validate = function(self, value)
+ local ipmasks= {}
+ string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
+ for index, ipmask in ipairs(ipmasks) do
+ if not datatypes.ipmask4(ipmask) then
+ return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
+ end
+ end
+ return value
+end
+
+---- Proxy Hosts
+local proxy_host = string.format("/usr/share/%s/rules/proxy_host", appname)
+o = s:taboption("proxy_list", TextValue, "proxy_host", "", "" .. translate("These had been joined websites will use proxy. Please input the domain names of websites,every line can input only one website domain. For example: google.com.") .. "")
+o.rows = 15
+o.wrap = "off"
+o.cfgvalue = function(self, section) return fs.readfile(proxy_host) or "" end
+o.write = function(self, section, value) fs.writefile(proxy_host, value:gsub("\r\n", "\n")) end
+o.remove = function(self, section, value) fs.writefile(proxy_host, "") end
+o.validate = function(self, value)
+ local hosts= {}
+ string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
+ for index, host in ipairs(hosts) do
+ if not datatypes.hostname(host) then
+ return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
+ end
+ end
+ return value
+end
+
+---- Proxy IP
+local proxy_ip = string.format("/usr/share/%s/rules/proxy_ip", appname)
+o = s:taboption("proxy_list", TextValue, "blacklist_ip", "", "" .. translate("These had been joined ip addresses will use proxy.Please input the ip address or ip address segment,every line can input only one ip address.For example: 35.24.0.0/24 or 8.8.4.4.") .. "")
+o.rows = 15
+o.wrap = "off"
+o.cfgvalue = function(self, section) return fs.readfile(proxy_ip) or "" end
+o.write = function(self, section, value) fs.writefile(proxy_ip, value:gsub("\r\n", "\n")) end
+o.remove = function(self, section, value) fs.writefile(proxy_ip, "") end
+o.validate = function(self, value)
+ local ipmasks= {}
+ string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
+ for index, ipmask in ipairs(ipmasks) do
+ if not datatypes.ipmask4(ipmask) then
+ return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
+ end
+ end
+ return value
+end
+
+return m
diff --git a/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po b/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po
index 240a65c0b5..4667a08d1b 100644
--- a/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po
+++ b/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po
@@ -70,6 +70,9 @@ msgstr "进入界面"
msgid "Rule Manage"
msgstr "规则管理"
+msgid "Rule List Manage"
+msgstr "直连/代理名单管理"
+
msgid "Access control"
msgstr "访问控制"
@@ -763,6 +766,12 @@ msgstr "加入的域名将走代理。输入网站域名,如:google.com,
msgid "These had been joined ip addresses will use proxy.Please input the ip address or ip address segment,every line can input only one ip address.For example: 35.24.0.0/24 or 8.8.4.4."
msgstr "加入的IP段将走代理。可输入IP地址或地址段,如:35.24.0.0/24或8.8.4.4,每个地址段一行。"
+msgid "Not valid domain name, please re-enter!"
+msgstr "不是有效域名,请重新输入!"
+
+msgid "Not valid IP format, please re-enter!"
+msgstr "不是有效IP格式,请重新输入!"
+
msgid "Clear logs"
msgstr "清空日志"
diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/direct_ip b/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/direct_ip
index 3fa82b7e00..5ea1a48e16 100644
--- a/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/direct_ip
+++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/direct_ip
@@ -3,5 +3,9 @@
223.5.5.5
223.6.6.6
119.29.29.29
+182.254.116.116
1.2.4.8
-210.2.4.8
\ No newline at end of file
+210.2.4.8
+101.226.4.6
+218.30.118.6
+180.76.76.76
diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_host b/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_host
index 2d26e3c029..ce2422f8c8 100644
--- a/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_host
+++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_host
@@ -132,3 +132,7 @@ xboxlive.com
youtu.be
youtube.com
ytimg.com
+dns.google
+cloudflare-dns.com
+one.one.one.one
+dns.quad9.net
diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_ip b/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_ip
index 0938095ef5..fd5eb772df 100644
--- a/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_ip
+++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/rules/proxy_ip
@@ -4,4 +4,10 @@
109.239.140.0/24
67.198.55.0/24
8.8.4.4
-8.8.8.8
\ No newline at end of file
+8.8.8.8
+208.67.222.222
+208.67.220.220
+1.1.1.1
+1.0.0.1
+9.9.9.9
+149.112.112.112