Browse Source

luci-compat: support dns forwarding feature

Nick Peng 2 years ago
parent
commit
0b723168bb

+ 137 - 7
package/luci-compat/files/luci/i18n/smartdns.zh-cn.po

@@ -22,7 +22,7 @@ msgstr "自动设置为Dnsmasq的上游服务器"
 msgid "Cache Size"
 msgid "Cache Size"
 msgstr "缓存大小"
 msgstr "缓存大小"
 
 
-msgid "Collecting data ..."
+msgid "Collecting data..."
 msgstr "正在收集数据..."
 msgstr "正在收集数据..."
 
 
 msgid ""
 msgid ""
@@ -30,12 +30,27 @@ msgid ""
 "DNS server."
 "DNS server."
 msgstr "配置需要从指定域名服务器结果过滤的IP黑名单。"
 msgstr "配置需要从指定域名服务器结果过滤的IP黑名单。"
 
 
+msgid "Configure block domain list."
+msgstr "配置屏蔽域名列表"
+
+msgid "Configure forwarding domain name list."
+msgstr "配置分流域名列表"
+
 msgid "Custom Settings"
 msgid "Custom Settings"
 msgstr "自定义设置"
 msgstr "自定义设置"
 
 
+msgid "DNS Block Setting"
+msgstr "域名屏蔽设置"
+
+msgid "DNS Forwarding Setting"
+msgstr "域名分流设置"
+
 msgid "DNS Server Name"
 msgid "DNS Server Name"
 msgstr "DNS服务器名称"
 msgstr "DNS服务器名称"
 
 
+msgid "DNS Server group belongs to, such as office, home."
+msgstr "配置归属服务器组,例如office, home"
+
 msgid ""
 msgid ""
 "DNS Server group belongs to, used with nameserver, such as office, home."
 "DNS Server group belongs to, used with nameserver, such as office, home."
 msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。"
 msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。"
@@ -52,8 +67,8 @@ msgstr "协议类型"
 msgid "DNS domain result cache size"
 msgid "DNS domain result cache size"
 msgstr "缓存DNS的结果,缓存大小,配置零则不缓存"
 msgstr "缓存DNS的结果,缓存大小,配置零则不缓存"
 
 
-msgid "Dnsmasq Forwared To Smartdns Failure"
-msgstr "重定向dnsmasq到smartdns失败"
+msgid "Description"
+msgstr "描述"
 
 
 msgid "Do not check certificate."
 msgid "Do not check certificate."
 msgstr "不校验证书的合法性。"
 msgstr "不校验证书的合法性。"
@@ -64,6 +79,18 @@ msgstr "禁用测速。"
 msgid "Domain Address"
 msgid "Domain Address"
 msgstr "域名地址"
 msgstr "域名地址"
 
 
+msgid "Domain List"
+msgstr "域名列表"
+
+msgid "Domain List File"
+msgstr "域名列表文件"
+
+msgid "Domain Rules"
+msgstr "域名规则"
+
+msgid "Domain Rules Settings"
+msgstr "域名规则设置"
+
 msgid "Domain TTL"
 msgid "Domain TTL"
 msgstr "域名TTL"
 msgstr "域名TTL"
 
 
@@ -82,12 +109,26 @@ msgstr "捐助"
 msgid "Donate to smartdns"
 msgid "Donate to smartdns"
 msgstr "捐助smartdns项目"
 msgstr "捐助smartdns项目"
 
 
+msgid "Download Files"
+msgstr "下载文件"
+
+msgid "Download Files Setting"
+msgstr "下载文件设置"
+
+msgid ""
+"Download domain list files for domain-rule and include config files, please "
+"refresh the page after download to take effect."
+msgstr "下载域名文件列表,下载后刷新页面生效"
+
 msgid "Dual-stack IP Selection"
 msgid "Dual-stack IP Selection"
 msgstr "双栈IP优选"
 msgstr "双栈IP优选"
 
 
 msgid "Enable"
 msgid "Enable"
 msgstr "启用"
 msgstr "启用"
 
 
+msgid "Enable Auto Update"
+msgstr "启用自动更新"
+
 msgid "Enable IP selection between IPV4 and IPV6"
 msgid "Enable IP selection between IPV4 and IPV6"
 msgstr "启用 IPV4 和 IPV6 间的 IP 优选策略"
 msgstr "启用 IPV4 和 IPV6 间的 IP 优选策略"
 
 
@@ -97,6 +138,9 @@ msgstr "启用IPV6服务器"
 msgid "Enable TCP DNS Server"
 msgid "Enable TCP DNS Server"
 msgstr "启用TCP服务器"
 msgstr "启用TCP服务器"
 
 
+msgid "Enable daily auto update."
+msgstr "启用每日自动更新。"
+
 msgid "Enable domain prefetch, accelerate domain response speed."
 msgid "Enable domain prefetch, accelerate domain response speed."
 msgstr "启用域名预加载,加速域名响应速度。"
 msgstr "启用域名预加载,加速域名响应速度。"
 
 
@@ -106,6 +150,18 @@ msgstr "是否启用第二DNS服务器。"
 msgid "Enable or disable smartdns server"
 msgid "Enable or disable smartdns server"
 msgstr "启用或禁用SmartDNS服务"
 msgstr "启用或禁用SmartDNS服务"
 
 
+msgid "Exclude DNS Server from default group."
+msgstr "从default默认服务器组中排除"
+
+msgid "Exclude Default Group"
+msgstr "从默认服务器组排除"
+
+msgid "File Name"
+msgstr "文件名"
+
+msgid "File Type"
+msgstr "文件类型"
+
 msgid "Filtering IP with blacklist"
 msgid "Filtering IP with blacklist"
 msgstr "使用IP黑名单过滤"
 msgstr "使用IP黑名单过滤"
 
 
@@ -133,9 +189,6 @@ msgid ""
 msgstr ""
 msgstr ""
 "当smartdns异常时生成coredump文件,coredump文件在/tmp/smartdns.xxx.core."
 "当smartdns异常时生成coredump文件,coredump文件在/tmp/smartdns.xxx.core."
 
 
-msgid "Grant access to LuCI app smartdns"
-msgstr "授予访问 LuCI 应用 smartdns 的权限"
-
 msgid "HTTP Host"
 msgid "HTTP Host"
 msgstr "HTTP主机"
 msgstr "HTTP主机"
 
 
@@ -148,9 +201,26 @@ msgstr "IP黑名单过滤"
 msgid "IPV6 Server"
 msgid "IPV6 Server"
 msgstr "IPV6服务器"
 msgstr "IPV6服务器"
 
 
+msgid "IPset Name"
+msgstr "IPSet名称"
+
+msgid "IPset name."
+msgstr "IPSet名称。"
+
 msgid "If you like this software, please buy me a cup of coffee."
 msgid "If you like this software, please buy me a cup of coffee."
 msgstr "如果本软件对你有帮助,请给作者加个蛋。"
 msgstr "如果本软件对你有帮助,请给作者加个蛋。"
 
 
+msgid "Include Config Files<br>/etc/smartdns/conf.d"
+msgstr "包含配置文件"
+
+msgid ""
+"Include other config files from /etc/smartdns/conf.d or custom path, can be "
+"downloaded from the download page."
+msgstr "包含配置文件,路径为/etc/smartdns/conf.d,或自定义配置文件路径,可以从下载页"
+
+msgid "List of files to download."
+msgstr "下载的文件列表。"
+
 msgid "Local Port"
 msgid "Local Port"
 msgstr "本地端口"
 msgstr "本地端口"
 
 
@@ -160,6 +230,15 @@ msgstr "所有域名的最大 TTL 值。"
 msgid "Minimum TTL for all domain result."
 msgid "Minimum TTL for all domain result."
 msgstr "所有域名的最小 TTL 值。"
 msgstr "所有域名的最小 TTL 值。"
 
 
+msgid "NFTset Name"
+msgstr "NFTSet名称"
+
+msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]"
+msgstr "NFTSet名称格式错误,格式:[#[4|6]:[family#table#set]]"
+
+msgid "NFTset name, format: [#[4|6]:[family#table#set]]"
+msgstr "NFTSet名称,格式:[#[4|6]:[family#table#set]]"
+
 msgid "NOT RUNNING"
 msgid "NOT RUNNING"
 msgstr "未运行"
 msgstr "未运行"
 
 
@@ -184,6 +263,12 @@ msgstr "解析本地主机名"
 msgid "Resolve local hostnames by reading Dnsmasq lease file."
 msgid "Resolve local hostnames by reading Dnsmasq lease file."
 msgstr "读取Dnsmasq的租约文件解析本地主机名。"
 msgstr "读取Dnsmasq的租约文件解析本地主机名。"
 
 
+msgid "Restart"
+msgstr "重启"
+
+msgid "Restart smartdns"
+msgstr "重启服务"
+
 msgid "Second Server Settings"
 msgid "Second Server Settings"
 msgstr "第二DNS服务器"
 msgstr "第二DNS服务器"
 
 
@@ -193,6 +278,9 @@ msgstr "缓存过期服务"
 msgid "Server Group"
 msgid "Server Group"
 msgstr "服务器组"
 msgstr "服务器组"
 
 
+msgid "Server Group not exists"
+msgstr "服务器组不存在"
+
 msgid "Server Name"
 msgid "Server Name"
 msgstr "服务器名称"
 msgstr "服务器名称"
 
 
@@ -275,7 +363,8 @@ msgstr "SmartDNS本地服务端口"
 msgid ""
 msgid ""
 "Smartdns local server port, smartdns will be automatically set as main dns "
 "Smartdns local server port, smartdns will be automatically set as main dns "
 "when the port is 53."
 "when the port is 53."
-msgstr "SmartDNS本地服务端口,当端口号设置为53时,smartdns将会自动配置为主dns。"
+msgstr ""
+"SmartDNS本地服务端口,当端口号设置为53时,smartdns将会自动配置为主dns。"
 
 
 msgid "Smartdns server name"
 msgid "Smartdns server name"
 msgstr "SmartDNS的服务器名称,默认为smartdns,留空为主机名"
 msgstr "SmartDNS的服务器名称,默认为smartdns,留空为主机名"
@@ -306,6 +395,38 @@ msgstr "设置所有域名的 TTL 值。"
 msgid "Technical Support"
 msgid "Technical Support"
 msgstr "技术支持"
 msgstr "技术支持"
 
 
+msgid "URL"
+msgstr "URL"
+
+msgid "URL format error, format: http:// or https://"
+msgstr "URL格式错误,格式:http://或https://"
+
+msgid "Update Files"
+msgstr "更新文件"
+
+msgid "Upload Config File"
+msgstr "上传域名列表文件"
+
+msgid "Upload Domain List File"
+msgstr "上传域名列表文件"
+
+msgid "Upload domain list file to /etc/smartdns/domain-set"
+msgstr "上传域名列表文件到/etc/smartdns/domain-set目录"
+
+msgid ""
+"Upload domain list file, or configure auto download from Download File "
+"Setting page."
+msgstr "上传域名列表文件,或在下载文件设置页面设置自动下载。"
+
+msgid "Upload domain list file."
+msgstr "上传域名列表文件。"
+
+msgid "Upload smartdns config file to /etc/smartdns/conf.d"
+msgstr "上传配置文件到/etc/smartdns/conf.d目录"
+
+msgid "Upstream DNS Server Configuration"
+msgstr "上游服务器配置"
+
 msgid "Upstream Servers"
 msgid "Upstream Servers"
 msgstr "上游服务器"
 msgstr "上游服务器"
 
 
@@ -324,6 +445,9 @@ msgstr ""
 "用于校验 TLS 服务器的有效性,数值为 Base64 编码的 SPKI 指纹,留空表示不验证 "
 "用于校验 TLS 服务器的有效性,数值为 Base64 编码的 SPKI 指纹,留空表示不验证 "
 "TLS 的合法性。"
 "TLS 的合法性。"
 
 
+msgid "domain list (/etc/smartdns/domain-set)"
+msgstr "域名列表(/etc/smartdns/domain-set)"
+
 msgid "https"
 msgid "https"
 msgstr "https"
 msgstr "https"
 
 
@@ -336,6 +460,9 @@ msgstr "打开网站"
 msgid "port"
 msgid "port"
 msgstr "端口"
 msgstr "端口"
 
 
+msgid "smartdns config (/etc/smartdns/conf.d)"
+msgstr "配置文件(/etc/smartdns/conf.d)"
+
 msgid "smartdns custom settings"
 msgid "smartdns custom settings"
 msgstr "smartdns 自定义设置,具体配置参数参考指导"
 msgstr "smartdns 自定义设置,具体配置参数参考指导"
 
 
@@ -350,3 +477,6 @@ msgstr "类型"
 
 
 msgid "udp"
 msgid "udp"
 msgstr "udp"
 msgstr "udp"
+
+msgid "update domain list files"
+msgstr "更新列表文件"

+ 220 - 16
package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua

@@ -19,6 +19,8 @@ require ("luci.http")
 require ("luci.dispatcher")
 require ("luci.dispatcher")
 require ("nixio.fs")
 require ("nixio.fs")
 
 
+local uci = require "luci.model.uci".cursor()
+
 m = Map("smartdns")
 m = Map("smartdns")
 m.title	= translate("SmartDNS Server")
 m.title	= translate("SmartDNS Server")
 m.description = translate("SmartDNS is a local high-performance DNS server, supports finding fastest IP, supports ad filtering, and supports avoiding DNS poisoning.")
 m.description = translate("SmartDNS is a local high-performance DNS server, supports finding fastest IP, supports ad filtering, and supports avoiding DNS poisoning.")
@@ -30,6 +32,7 @@ s = m:section(TypedSection, "smartdns", translate("Settings"), translate("Genera
 s.anonymous = true
 s.anonymous = true
 
 
 s:tab("settings", translate("General Settings"))
 s:tab("settings", translate("General Settings"))
+s:tab("advanced", translate('Advanced Settings'))
 s:tab("seconddns", translate("Second Server Settings"))
 s:tab("seconddns", translate("Second Server Settings"))
 s:tab("custom", translate("Custom Settings"))
 s:tab("custom", translate("Custom Settings"))
 
 
@@ -69,7 +72,7 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 ---- Support DualStack ip selection
 ---- Support DualStack ip selection
-o = s:taboption("settings", Flag, "dualstack_ip_selection", translate("Dual-stack IP Selection"), translate("Enable IP selection between IPV4 and IPV6"))
+o = s:taboption("advanced", Flag, "dualstack_ip_selection", translate("Dual-stack IP Selection"), translate("Enable IP selection between IPV4 and IPV6"))
 o.rmempty     = false
 o.rmempty     = false
 o.default     = o.enabled
 o.default     = o.enabled
 o.cfgvalue    = function(...)
 o.cfgvalue    = function(...)
@@ -77,7 +80,7 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 ---- Domain prefetch load 
 ---- Domain prefetch load 
-o = s:taboption("settings", Flag, "prefetch_domain", translate("Domain prefetch"), translate("Enable domain prefetch, accelerate domain response speed."))
+o = s:taboption("advanced", Flag, "prefetch_domain", translate("Domain prefetch"), translate("Enable domain prefetch, accelerate domain response speed."))
 o.rmempty     = false
 o.rmempty     = false
 o.default     = o.disabled
 o.default     = o.disabled
 o.cfgvalue    = function(...)
 o.cfgvalue    = function(...)
@@ -85,7 +88,7 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 ---- Domain Serve expired
 ---- Domain Serve expired
-o = s:taboption("settings", Flag, "serve_expired", translate("Serve expired"), 
+o = s:taboption("advanced", Flag, "serve_expired", translate("Serve expired"), 
 	translate("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."))
 	translate("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."))
 o.rmempty     = false
 o.rmempty     = false
 o.default     = o.enabled
 o.default     = o.enabled
@@ -94,11 +97,11 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 ---- cache-size
 ---- cache-size
-o = s:taboption("settings", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size"))
+o = s:taboption("advanced", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size"))
 o.rempty      = true
 o.rempty      = true
 
 
 -- cache-size
 -- cache-size
-o = s:taboption("settings", Flag, "resolve_local_hostnames", translate("Resolve Local Hostnames"), translate("Resolve local hostnames by reading Dnsmasq lease file."));
+o = s:taboption("advanced", Flag, "resolve_local_hostnames", translate("Resolve Local Hostnames"), translate("Resolve local hostnames by reading Dnsmasq lease file."))
 o.rmempty     = false
 o.rmempty     = false
 o.default     = o.enabled
 o.default     = o.enabled
 o.cfgvalue    = function(...)
 o.cfgvalue    = function(...)
@@ -106,7 +109,7 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 -- Automatically Set Dnsmasq
 -- Automatically Set Dnsmasq
-o = s:taboption("settings", Flag, "auto_set_dnsmasq", translate("Automatically Set Dnsmasq"), translate("Automatically set as upstream of dnsmasq when port changes."));
+o = s:taboption("advanced", Flag, "auto_set_dnsmasq", translate("Automatically Set Dnsmasq"), translate("Automatically set as upstream of dnsmasq when port changes."))
 o.rmempty     = false
 o.rmempty     = false
 o.default     = o.enabled
 o.default     = o.enabled
 o.cfgvalue    = function(...)
 o.cfgvalue    = function(...)
@@ -114,7 +117,7 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 -- Force AAAA SOA
 -- Force AAAA SOA
-o = s:taboption("settings", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."));
+o = s:taboption("advanced", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
 o.rmempty     = false
 o.rmempty     = false
 o.default     = o.enabled
 o.default     = o.enabled
 o.cfgvalue    = function(...)
 o.cfgvalue    = function(...)
@@ -122,7 +125,7 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 -- Force HTTPS SOA
 -- Force HTTPS SOA
-o = s:taboption("settings", Flag, "force_https_soa", translate("Force HTTPS SOA"), translate("Force HTTPS SOA."));
+o = s:taboption("advanced", Flag, "force_https_soa", translate("Force HTTPS SOA"), translate("Force HTTPS SOA."))
 o.rmempty     = false
 o.rmempty     = false
 o.default     = o.enabled
 o.default     = o.enabled
 o.cfgvalue    = function(...)
 o.cfgvalue    = function(...)
@@ -130,24 +133,35 @@ o.cfgvalue    = function(...)
 end
 end
 
 
 ---- rr-ttl
 ---- rr-ttl
-o = s:taboption("settings", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result."))
+o = s:taboption("advanced", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result."))
 o.rempty      = true
 o.rempty      = true
 
 
 ---- rr-ttl-min
 ---- rr-ttl-min
-o = s:taboption("settings", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result."))
+o = s:taboption("advanced", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result."))
 o.rempty      = true
 o.rempty      = true
 o.placeholder = "600"
 o.placeholder = "600"
 o.default     = 600
 o.default     = 600
 o.optional    = true
 o.optional    = true
 
 
 ---- rr-ttl-max
 ---- rr-ttl-max
-o = s:taboption("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result."))
+o = s:taboption("advanced", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result."))
 o.rempty      = true
 o.rempty      = true
 
 
 ---- rr-ttl-reply-max
 ---- rr-ttl-reply-max
-o = s:taboption("settings", Value, "rr_ttl_reply_max", translate("Reply Domain TTL Max"), translate("Reply maximum TTL for all domain result."))
+o = s:taboption("advanced", Value, "rr_ttl_reply_max", translate("Reply Domain TTL Max"), translate("Reply maximum TTL for all domain result."))
 o.rempty      = true
 o.rempty      = true
 
 
+o = s:taboption("advanced", DynamicList, "conf_files", translate("Include Config Files<br>/etc/smartdns/conf.d"),
+    translate("Include other config files from /etc/smartdns/conf.d or custom path, can be downloaded from the download page."));
+uci:foreach("smartdns", "download-file", function(section)
+    local filetype = section.type
+    if (filetype ~= 'config') then
+        return
+    end
+
+    o:value(section.name);
+end)
+
 ---- second dns server
 ---- second dns server
 ---- Eanble
 ---- Eanble
 o = s:taboption("seconddns", Flag, "seconddns_enabled", translate("Enable"), translate("Enable or disable second DNS server."))
 o = s:taboption("seconddns", Flag, "seconddns_enabled", translate("Enable"), translate("Enable or disable second DNS server."))
@@ -305,11 +319,122 @@ o:value("https", translate("https"))
 o.default     = "udp"
 o.default     = "udp"
 o.rempty      = false
 o.rempty      = false
 
 
-s = m:section(TypedSection, "smartdns", translate("Advanced Settings"), translate("Advanced Settings"));
-s.anonymous = true;
+---- domain rules;
+s = m:section(TypedSection, "domain-rule", translate("Domain Rules"), translate("Domain Rules Settings"))
+s.anonymous = true
+s.nodescriptions = true
+
+s:tab("forwarding", translate('DNS Forwarding Setting'))
+s:tab("block", translate("DNS Block Setting"))
+s:tab("domain-address", translate("Domain Address"), translate("Set Specific domain ip address."))
+s:tab("blackip-list", translate("IP Blacklist"), translate("Set Specific ip blacklist."))
+
+---- domain forwarding;
+o = s:taboption("forwarding", Value, "server_group", translate("Server Group"), translate("DNS Server group belongs to, such as office, home."))
+o.rmempty = true
+o.placeholder = "default"
+o.datatype = "hostname"
+o.rempty = true
+uci:foreach("smartdns", "server", function(section)
+    local server_group = section.server_group
+    o:value(server_group);
+end)
+
+function o.validate (section_id, value) 
+    if (value == "") then
+        return value
+    end
+
+    local exists = false
+    uci:foreach("smartdns", "server", function(section)
+        local server_group = section.server_group
+        if (exists == true) then
+            return
+        end
+
+        if (value == server_group) then
+            exists = true
+        end
+    end)
+
+    if (exists == false) then
+        return nil, translate('Server Group not exists')
+    end
+
+    return value;
+
+end
+
+o = s:taboption("forwarding", Flag, "no_speed_check", translate("Skip Speed Check"),
+    translate("Do not check speed."))
+o.rmempty = false
+o.default = o.disabled
+
+o = s:taboption("forwarding", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
+o.rmempty = false
+o.default = o.disabled
+
+o = s:taboption("forwarding", Value, "ipset_name", translate("IPset Name"), translate("IPset name."))
+o.rmempty = true
+o.datatype = "hostname"
+o.rempty = true
+
+o = s:taboption("forwarding", Value, "nftset_name", translate("NFTset Name"), translate("NFTset name, format: [#[4|6]:[family#table#set]]"))
+o.rmempty = true
+o.datatype = "string"
+o.rempty = true
+function o.validate(self, value) 
+    if (value == "") then
+        return value
+    end
+
+    if (value:match("#[4|6]:[a-zA-Z0-9%-_]+#[a-zA-Z0-9%-_]+#[a-zA-Z0-9%-_]+$")) then
+        return value
+    end
+
+    return nil, translate("NFTset name format error, format: [#[4|6]:[family#table#set]]")
+end
+
+o = s:taboption("forwarding", FileUpload, "forwarding_domain_set_file", translate("Domain List File"),
+    translate("Upload domain list file, or configure auto download from Download File Setting page."))
+o.rmempty = true
+o.datatype = "file"
+o.rempty = true
+o.editable = true
+o.root_directory = "/etc/smartdns/domain-set"
+
+o = s:taboption("forwarding", TextValue, "domain_forwarding_list",
+    translate("Domain List"), translate("Configure forwarding domain name list."))
+o.rows = 10
+o.cols = 64
+o.monospace = true
+function o.cfgvalue(self, section)
+	return nixio.fs.readfile("/etc/smartdns/domain-forwarding.list")
+end
+function o.write(self, section, value)
+	value = value:gsub("\r\n?", "\n")
+	nixio.fs.writefile("/etc/smartdns/domain-forwarding.list", value)
+end
 
 
-s:tab("domain-address", translate("Domain Address"), translate("Set Specific domain ip address."));
-s:tab("blackip-list", translate("IP Blacklist"), translate("Set Specific ip blacklist."));
+---- domain block;
+o = s:taboption("block", FileUpload, "block_domain_set_file", translate("Domain List File"), translate("Upload domain list file."))
+o.rmempty = true
+o.datatype = "file"
+o.rempty = true
+o.editable = true
+o.root_directory = "/etc/smartdns/domain-set"
+
+o = s:taboption("block", TextValue, "domain_block_list",
+    translate("Domain List"), translate("Configure block domain list."))
+o.rows = 10
+o.cols = 64
+function o.cfgvalue(self, section)
+	return nixio.fs.readfile("/etc/smartdns/domain-block.list")
+end
+function o.write(self, section, value)
+	value = value:gsub("\r\n?", "\n")
+	nixio.fs.writefile("/etc/smartdns/domain-block.list", value)
+end
 
 
 -- Doman addresss
 -- Doman addresss
 addr = s:taboption("domain-address", Value, "address",
 addr = s:taboption("domain-address", Value, "address",
@@ -345,6 +470,77 @@ function addr.write(self, section, value)
 	nixio.fs.writefile("/etc/smartdns/blacklist-ip.conf", value)
 	nixio.fs.writefile("/etc/smartdns/blacklist-ip.conf", value)
 end
 end
 
 
+s = m:section(TypedSection, "smartdns", translate("Download Files Setting"), translate("Download domain list files for domain-rule and include config files, please refresh the page after download to take effect."))
+s.anonymous = true
+
+---- download Files Settings
+o = s:option(Flag, "enable_auto_update", translate("Enable Auto Update"), translate("Enable daily auto update."))
+o.rmempty = false
+o.default = o.disabled
+o.rempty = true
+
+o = s:option(FileUpload, "upload_conf_file", translate("Upload Config File"),
+    translate("Upload smartdns config file to /etc/smartdns/conf.d"))
+o.rmempty = true
+o.datatype = "file"
+o.rempty = true
+o.editable = true
+o.root_directory = "/etc/smartdns/conf.d"
+
+o = s:option(FileUpload, "upload_list_file", translate("Upload Domain List File"),
+    translate("Upload domain list file to /etc/smartdns/domain-set"))
+o.rmempty = true
+o.datatype = "file"
+o.rempty = true
+o.editable = true
+o.root_directory = "/etc/smartdns/domain-set"
+
+o = s:option(Button, "_updateate")
+o.title = translate("Update Files")
+o.inputtitle = translate("update domain list files")
+o.inputstyle = "apply"
+o.write = function()
+	luci.sys.call("/etc/init.d/smartdns updatefiles >/dev/null 2>&1")
+end
+
+s = m:section(TypedSection, "download-file", translate("Download Files"), translate("List of files to download."))
+s.anonymous = true
+s.addremove = true
+s.template = "cbi/tblsection"
+
+o = s:option(Value, 'name', translate('File Name'), translate('File Name'))
+o.rmempty = false
+o.datatype = 'string'
+
+o = s:option(Value, 'url', translate('URL'), translate('URL'))
+o.rmempty = false
+o.datatype = 'string'
+function o.validate(self, value, section)
+    if value == "" then
+        return nil
+    end
+
+    if value.find(value, "http://") then
+        return value
+    end
+
+    if value.find(value, "https://") then
+        return value
+    end
+
+    return nil, translate("URL format error, format: http:// or https://")
+end
+
+o = s:option(ListValue, "type", translate("type"), translate("File Type"))
+o:value("list", translate("domain list (/etc/smartdns/domain-set)"))
+o:value("config", translate("smartdns config (/etc/smartdns/conf.d)"))
+o.default = "list"
+o.rempty = false
+
+o = s:option(Value, 'desc', translate('Description'), translate('Description'))
+o.rmempty = true
+o.datatype = 'string'
+
 -- Technical Support
 -- Technical Support
 s = m:section(TypedSection, "smartdns", translate("Technical Support"), 
 s = m:section(TypedSection, "smartdns", translate("Technical Support"), 
 	translate("If you like this software, please buy me a cup of coffee."))
 	translate("If you like this software, please buy me a cup of coffee."))
@@ -366,5 +562,13 @@ o.write = function()
 	luci.http.redirect("https://pymumu.github.io/smartdns/#donate")
 	luci.http.redirect("https://pymumu.github.io/smartdns/#donate")
 end
 end
 
 
+o = s:option(Button, "Restart")
+o.title = translate("Restart smartdns")
+o.inputtitle = translate("Restart")
+o.inputstyle = "apply"
+o.write = function()
+	luci.sys.call("/etc/init.d/smartdns restart >/dev/null 2>&1")
+end
+
 return m
 return m
 
 

+ 7 - 0
package/luci-compat/files/luci/model/cbi/smartdns/upstream.lua

@@ -62,6 +62,13 @@ o.placeholder = "default"
 o.datatype    = "hostname"
 o.datatype    = "hostname"
 o.rempty      = true
 o.rempty      = true
 
 
+---- exclude default group
+o = s:option(Flag, "exclude_default_group", translate("Exclude Default Group"), translate("Exclude DNS Server from default group."))
+o.rmempty = false
+o.default = o.disabled
+o.editable = true
+o.modalonly = true
+
 ---- blacklist_ip
 ---- blacklist_ip
 o = s:option(Flag, "blacklist_ip", translate("IP Blacklist Filtering"), translate("Filtering IP with blacklist"))
 o = s:option(Flag, "blacklist_ip", translate("IP Blacklist Filtering"), translate("Filtering IP with blacklist"))
 o.rmempty     = false
 o.rmempty     = false

+ 22 - 0
package/luci-compat/files/usr/share/rpcd/acl.d/luci-app-smartdns.json

@@ -0,0 +1,22 @@
+{
+	"luci-app-smartdns": {
+		"description": "Grant access to LuCI app smartdns",
+		"read": {
+			"file": {
+				"/etc/smartdns/*": [ "read" ]
+			},
+			"ubus": {
+				"service": [ "list" ]
+			},
+			"uci": [ "smartdns" ]
+		},
+		"write": {
+			"file": {
+				"/etc/smartdns/*": [ "write" ],
+				"/etc/init.d/smartdns restart": [ "exec" ],
+				"/etc/init.d/smartdns updatefiles": [ "exec" ]
+			},
+			"uci": [ "smartdns" ]
+		}
+	}
+}

+ 1 - 0
package/luci-compat/make.sh

@@ -54,6 +54,7 @@ build()
 	build_tool
 	build_tool
 	mkdir $ROOT/root/usr/lib/lua/ -p
 	mkdir $ROOT/root/usr/lib/lua/ -p
 	cp $ROOT/files/luci $ROOT/root/usr/lib/lua/ -af
 	cp $ROOT/files/luci $ROOT/root/usr/lib/lua/ -af
+	cp $ROOT/files/usr $ROOT/root/ -af
 	
 	
 	#Generate Language
 	#Generate Language
 	$PO2LMO $ROOT/files/luci/i18n/smartdns.zh-cn.po $ROOT/root/usr/lib/lua/luci/i18n/smartdns.zh-cn.lmo
 	$PO2LMO $ROOT/files/luci/i18n/smartdns.zh-cn.po $ROOT/root/usr/lib/lua/luci/i18n/smartdns.zh-cn.lmo