Browse Source

luci: remove redirect feature and set as main dns server automatically when port is 53

Nick Peng 3 years ago
parent
commit
e6d533e2c5

+ 29 - 85
ReadMe.md

@@ -258,92 +258,29 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
    * 在 `Domain Address` 指定特定域名的 IP 地址,可用于广告屏蔽。
 
 3. 启用服务
-   
-   SmartDNS 服务生效方法有两种,一种是**直接作为主 DNS 服务**,另一种是**作为 DNSmasq 的上游**。
-   默认情况下,SmartDNS 采用第一种方式。如下两种方式根据需求选择即可。
-   
-   - **方法一:作为主 DNS 服务(默认方案)**
-     
-     * 启用 SmartDNS 的 53 端口重定向
-       
-       登录 OpenWrt 管理界面,点击 `Services` -> `SmartDNS` -> `redirect`,选择 `重定向 53 端口到 SmartDNS `启用 53 端口转发。
-     
-     * 检测转发服务是否配置成功
-       
-       执行
-       
-       ```shell
-       $ nslookup -querytype=ptr smartdns
-       ```
-       
-       查看命令结果中的 `name` 是否为 `smartdns` 或你的主机名,如果是则表示生效
-       
-       ```shell
-       $ nslookup -querytype=ptr smartdns
-       Server:         192.168.1.1
-       Address:        192.168.1.1#53
-       
-       Non-authoritative answer:
-       smartdns        name = smartdns.
-       ```
-     
-     * 界面提示重定向失败
-       
-       * 检查 `iptables` 和/或 `ip6tables` 命令是否正确安装。
-       
-       * OpenWrt 15.01 系统不支持 IPv6 重定向,如网络需要支持 IPv6,请将 DNSmasq 上游改为 SmartDNS,或者将 SmartDNS 的端口改为53,并停用 DNSmasq。
-       
-       * LEDE 系统请安装 IPv6 的 NAT 转发驱动。点击 `System` -> `Software`,点击 `Update lists` 更新软件列表后,安装 `ip6tables-mod-nat`。
-       
-       * 使用如下命令检查路由规则是否生效
-         
-         ```shell
-         iptables -t nat -L PREROUTING | grep REDIRECT
-         ```
-       
-       * 如转发功能不正常,请使用**方法二:作为 DNSmasq 的上游**。
-   
-   - **方法二:作为 DNSmasq 的上游**
-     
-     * **将 DNSmasq 的请求发送到 SmartDNS**
-       
-       登录 OpenWrt 管理界面,点击 `Services` -> `SmartDNS` -> `Redirect`,选择`作为 DNSmasq 的上游服务器`,设置 DNSmasq 的上游服务器为 SmartDNS。
      
-     * **检测上游服务是否配置成功**
-       
-         执行
-         
-         ```shell
-         $ nslookup -querytype=ptr smartdns
-         ```
-         
-         查看命令结果中的 `name` 是否为 `smartdns` 或你的主机名,如果是则表示生效
-         
-         ```shell
-         $ nslookup -querytype=ptr smartdns
-         Server:         192.168.1.1
-         Address:        192.168.1.1#53
-         
-         Non-authoritative answer:
-         smartdns        name = smartdns.
-         ```
-
-         或执行
-
-         ```shell
-         $ nslookup smartdns
-         ```
-
-         查看命令结果是否有解析出路由器的IP地址,如果是则表示生效。
-
-         或执行
-
-         ```shell
-         ping smartdns.
-         ```
-
-         检测ping是否解析对应主机的IP地址。
+  * 替换默认Dndmasq为主DNS。
+    
+    登录 OpenWrt 管理界面,点击 `Services` -> `SmartDNS` -> `port`,设置端口号为`53`,smartdns会自动接管主DNS服务器。
 
+  * 检测转发服务是否配置成功
+    
+    执行
+    
+    ```shell
+    $ nslookup -querytype=ptr smartdns
+    ```
+    
+    查看命令结果中的 `name` 是否为 `smartdns` 或你的主机名,如果是则表示生效
+    
+    ```shell
+    $ nslookup -querytype=ptr smartdns
+    Server:         192.168.1.1
+    Address:        192.168.1.1#53
+    
+    Non-authoritative answer:
+    smartdns        name = smartdns.
+       ```
 
 4. 启动服务
    
@@ -352,7 +289,14 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
 5. **注意:**
    
    * 如已经安装 ChinaDNS,建议将 ChinaDNS 的上游配置为 SmartDNS。
-   * SmartDNS 默认情况下将 53 端口的请求转发到 SmartDNS的 本地端口,此行为由 `Redirect` 配置选项控制。
+   * 当smartdns的端口为53时,将自动接管dnsmasq为主dns。配置其他端口时,会重新启用dnsmasq为主dns。
+   * 若在此过程中发生异常,可使用如下命令还原dnsmasq为主DNS
+
+   ```shell
+   uci delete dhcp.@dnsmasq[0].port
+   uci commit dhcp
+   /etc/init.d/dnsmasq restart
+   ```
 
 ### 华硕路由器原生固件 / 梅林固件
 

+ 11 - 45
ReadMe_en.md

@@ -240,11 +240,11 @@ https://github.com/pymumu/smartdns/releases
    There are two ways to use the SmartDNS service, `one is directly as the primary DNS service`, `the other is as the upstream of dnsmasq`.  
    By default, SmartDNS uses the first method. You can choose according to your needs in the following two ways.
 
-1. Method 1: SmartDNS as primary DNS Server (default scheme)
+1. Method 1: SmartDNS as primary DNS Server 
 
-    * **Enable SmartDNS port 53 port redirection**
+    * **Enable SmartDNS as primary DNS Server**
 
-        Log in to the router, click on `Services`->`SmartDNS`->`redirect`, select `Redirect 53 port to SmartDNS` option to enable port 53 forwarding.
+        Log in to the router, click on `Services`->`SmartDNS`->`port`, input port `53`, smartdns will run as primary DNS Server.
 
     * **Check if the service is configured successfully**
 
@@ -260,54 +260,20 @@ https://github.com/pymumu/smartdns/releases
         smartdns         name = smartdns.
         ```
 
-    * **The interface prompts that the redirect failed**
-
-        * Check if iptable, ip6table command is installed correctly.
-        * The openwrt 15.01 system does not support IPV6 redirection. If the network needs to support IPV6, please change DNSMASQ upstream to smartdns, or change the smartdns port to 53, and disable dnsmasq.
-        * After LEDE system, please install IPV6 nat forwarding driver. Click `system`->`Software`, click `update lists` to update the software list, install `ip6tables-mod-nat`
-        * Use the following command to check whether the routing rule takes effect.
-
-        ```shell
-        iptables -t nat -L PREROUTING | grep REDIRECT
-        ```
-
-        * If the forwarding function is abnormal, please use Method 2: As the upstream of DNSMASQ.
-
-1. Method 2: SmartDNS as upstream DNS Server of DNSMASQ
-
-    * **Forward dnsmasq's request to SmartDNS**
-
-        Log in to the router, click on `Services`->`SmartDNS`->`redirect`, select `Run as dnsmasq upstream server` option to forwarding dnsmasq request to Smartdns.
-
-    * **Check if the service is configured successfully**
-
-        * Query domain name with `nslookup -querytype=ptr 0.0.0.1`
-        See if the `name` item in the command result is displayed as `smartdns` or `hostname`, such as `smartdns`
-
-        ```shell
-        pi@raspberrypi:~/code/smartdns_build $ nslookup -querytype=ptr smartdns
-        Server:         192.168.1.1
-        Address:        192.168.1.1#53
-
-        Non-authoritative answer:
-        smartdns         name = smartdns.
-        ```
-
-        * or Query doman name `smartdns `with `nslookup smartdns`
-         ```shell
-         $ nslookup smartdns
-         ```
-
-        Check whether the command result resolves the IP address of the router, if so, it means it is working.
-
 1. Start Service
 
     Check the `Enable' in the configuration page to start SmartDNS server.
 
 1. Note
 
-    * If chinaDNS is already installed, it is recommended to configure the upstream of chinaDNS as SmartDNS.
-    * SmartDNS defaults to forwarding port 53 requests to the local port of SmartDNS, controlled by the `Redirect` configuration option.
+   * When the port of smartdns is 53, it will automatically take over dnsmasq as the primary dns. When configuring other ports, dnsmasq is re-enabled as primary dns.
+   * If an exception occurs during this process, you can use the following command to restore dnsmasq as the primary DNS
+
+   ```shell
+   uci delete dhcp.@dnsmasq[0].port
+   uci commit dhcp
+   /etc/init.d/dnsmasq restart
+   ```
 
 ### ASUS router native firmware / Merlin firmware
 

+ 0 - 40
package/luci-compat/files/luci/controller/smartdns.lua

@@ -37,47 +37,7 @@ end
 
 function act_status()
 	local e={}
-	local ipv6_server;
-	local redirect_mode="none";
-
-	e.ipv6_works = 2;
-	e.ipv4_works = 2;
-	e.ipv6_server = 1;
-	e.dnsmasq_forward = 0;
-	redirect_mode = smartdns.get_config_option("smartdns", "smartdns", "redirect", nil);
-	if redirect_mode == "redirect" then
-		e.redirect = 1
-	elseif redirect_mode == "dnsmasq-upstream" then
-		e.redirect = 2
-	else
-		e.redirect = 0
-	end
-
-	e.local_port = smartdns.get_config_option("smartdns", "smartdns", "port", nil);
-	ipv6_server = smartdns.get_config_option("smartdns", "smartdns", "ipv6_server", nil);
-	if e.redirect == 1 then 
-		if e.local_port ~= nil and e.local_port ~= "53" then
-			e.ipv4_works = luci.sys.call("iptables -t nat -nL PREROUTING 2>/dev/null | grep REDIRECT | grep dpt:53 | grep %q >/dev/null 2>&1" % e.local_port) == 0
-			if ipv6_server == "1" then
-				e.ipv6_works = luci.sys.call("ip6tables -t nat -nL PREROUTING 2>/dev/null| grep REDIRECT | grep dpt:53 | grep %q >/dev/null 2>&1" % e.local_port) == 0
-			else 
-				e.ipv6_works = 2
-			end
-		else
-			e.redirect = 0
-		end
-	elseif e.redirect == 2 then
-		local str;
-		local dnsmasq_server = luci.sys.exec("uci get dhcp.@dnsmasq[0].server")
-		if e.local_port ~= nil then
-			str = "127.0.0.1#" .. e.local_port 
-			if  string.sub(dnsmasq_server,1,string.len(str)) == str then 
-				e.dnsmasq_forward = 1
-			end
-		end
-	end
 	e.running = is_running()
-
 	luci.http.prepare_content("application/json")
 	luci.http.write_json(e)
 end

+ 235 - 193
package/luci-compat/files/luci/i18n/smartdns.zh-cn.po

@@ -1,182 +1,220 @@
-msgid ""
-msgstr "Content-Type: text/plain; charset=UTF-8\n"
 
-msgid "SmartDNS"
-msgstr "SmartDNS"
+msgid "Additional Args for upstream dns servers"
+msgstr "额外的上游 DNS 服务器参数"
 
-msgid "SmartDNS is a local high-performance DNS server"
-msgstr "SmartDNS是一个本地高性能DNS服务器"
+msgid "Additional Server Args"
+msgstr "额外的服务器参数"
 
-msgid "SmartDNS Server"
-msgstr "SmartDNS 服务器"
+msgid "Advanced Settings"
+msgstr "高级设置"
 
-msgid "SmartDNS is a local high-performance DNS server, supports finding fastest IP, supports ad filtering, and supports avoiding DNS poisoning."
-msgstr "SmartDNS是一个本地高性能DNS服务器,支持返回最快IP,支持广告过滤。"
+msgid ""
+"Attempts to serve old responses from cache with a TTL of 0 in the response "
+"without waiting for the actual resolution to finish."
+msgstr "查询性能优化,有请求时尝试回应TTL为0的过期记录,以避免查询等待。"
 
-msgid "Custom Settings"
-msgstr "自定义设置"
+msgid "Automatically Set Dnsmasq"
+msgstr "自动设置Dnsmasq"
 
-msgid "General Settings"
-msgstr "基本设置"
+msgid "Automatically set as upstream of dnsmasq when port changes."
+msgstr "自动设置为Dnsmasq的上游服务器"
 
-msgid "Settings"
-msgstr "设置"
+msgid "Cache Size"
+msgstr "缓存大小"
 
-msgid "Advanced Settings"
-msgstr "高级设置"
+msgid "Collecting data ..."
+msgstr "正在收集数据..."
 
-msgid "Generate Coredump"
-msgstr "生成coredump"
+msgid ""
+"Configure IP blacklists that will be filtered from the results of specific "
+"DNS server."
+msgstr "配置需要从指定域名服务器结果过滤的IP黑名单。"
 
-msgid "Generate Coredump file when smartdns crash, coredump file is located at /tmp/smartdns.xxx.core."
-msgstr "当smartdns异常时生成coredump文件,coredump文件在/tmp/smartdns.xxx.core."
+msgid "Custom Settings"
+msgstr "自定义设置"
 
-msgid "Server Name"
-msgstr "服务器名称"
+msgid "DNS Server Name"
+msgstr "DNS服务器名称"
 
-msgid "Smartdns server name"
-msgstr "SmartDNS的服务器名称,默认为smartdns,留空为主机名"
+msgid ""
+"DNS Server group belongs to, used with nameserver, such as office, home."
+msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。"
 
-msgid "SmartDNS is a local dns server to find fastest ip."
-msgstr "本地高性能服务器,优化网络访问性能。"
+msgid "DNS Server ip"
+msgstr "DNS服务器IP"
 
-msgid "Enable or disable smartdns server"
-msgstr "启用或禁用SmartDNS服务"
+msgid "DNS Server port"
+msgstr "DNS服务器端口"
 
-msgid "Local Port"
-msgstr "本地端口"
+msgid "DNS Server type"
+msgstr "协议类型"
 
-msgid "Smartdns local server port"
-msgstr "SmartDNS本地服务端口"
+msgid "DNS domain result cache size"
+msgstr "缓存DNS的结果,缓存大小,配置零则不缓存"
 
-msgid "IPV4 53 Port Redirect Failure"
-msgstr "IPV4 53端口重定向失败"
+msgid "Do not check certificate."
+msgstr "不校验证书的合法性。"
 
-msgid "IPV6 53 Port Redirect Failure"
-msgstr "IPV6 53端口重定向失败"
+msgid "Do not check speed."
+msgstr "禁用测速。"
 
-msgid "Dnsmasq Forwared To Smartdns Failure"
-msgstr "重定向dnsmasq到smartdns失败"
+msgid "Domain Address"
+msgstr "域名地址"
 
-msgid "TCP Server"
-msgstr "TCP服务器"
+msgid "Domain TTL"
+msgstr "域名TTL"
 
-msgid "Enable TCP DNS Server"
-msgstr "启用TCP服务器"
+msgid "Domain TTL Max"
+msgstr "域名TTL最大值"
 
-msgid "IPV6 Server"
-msgstr "IPV6服务器"
+msgid "Domain TTL Min"
+msgstr "域名TTL最小值"
 
-msgid "Enable IPV6 DNS Server"
-msgstr "启用IPV6服务器"
+msgid "Domain prefetch"
+msgstr "域名预加载"
+
+msgid "Donate"
+msgstr "捐助"
+
+msgid "Donate to smartdns"
+msgstr "捐助smartdns项目"
 
 msgid "Dual-stack IP Selection"
 msgstr "双栈IP优选"
 
+msgid "Enable"
+msgstr "启用"
+
 msgid "Enable IP selection between IPV4 and IPV6"
-msgstr "启用或禁用IPV4,IPV6间的IP优选策略。"
+msgstr "启用 IPV4 和 IPV6 间的 IP 优选策略"
 
-msgid "Domain prefetch"
-msgstr "域名预加载"
+msgid "Enable IPV6 DNS Server"
+msgstr "启用IPV6服务器"
+
+msgid "Enable TCP DNS Server"
+msgstr "启用TCP服务器"
 
 msgid "Enable domain prefetch, accelerate domain response speed."
 msgstr "启用域名预加载,加速域名响应速度。"
 
-msgid "Serve expired"
-msgstr "过期缓存服务"
+msgid "Enable or disable second DNS server."
+msgstr "是否启用第二DNS服务器。"
 
-msgid "Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."
-msgstr "查询性能优化,有请求时尝试回应TTL为0的过期记录,以避免查询等待。"
+msgid "Enable or disable smartdns server"
+msgstr "启用或禁用SmartDNS服务"
 
-msgid "Redirect"
-msgstr "重定向"
+msgid "Filtering IP with blacklist"
+msgstr "使用IP黑名单过滤"
 
-msgid "SmartDNS redirect mode"
-msgstr "SmartDNS 重定向模式"
+msgid "Force AAAA SOA"
+msgstr "停用IPV6地址解析"
 
-msgid "Run as dnsmasq upstream server"
-msgstr "作为dnsmasq的上游服务器"
+msgid "Force AAAA SOA."
+msgstr "停用IPV6地址解析。"
 
-msgid "Redirect 53 port to SmartDNS"
-msgstr "重定向53端口到SmartDNS"
+msgid "Force HTTPS SOA"
+msgstr "停用HTTPS地址解析"
 
-msgid "Cache Size"
-msgstr "缓存大小"
+msgid "Force HTTPS SOA."
+msgstr "停用HTTPS地址解析。"
 
-msgid "DNS domain result cache size"
-msgstr "缓存DNS的结果,缓存大小,配置零则不缓存(单位:条)"
+msgid "General Settings"
+msgstr "常规设置"
 
-msgid "Domain TTL"
-msgstr "域名TTL"
+msgid "Generate Coredump"
+msgstr "生成coredump"
 
-msgid "TTL for all domain result."
-msgstr "设置所有域名的TTL值(单位:秒,下同)"
+msgid ""
+"Generate Coredump file when smartdns crash, coredump file is located at /tmp/"
+"smartdns.xxx.core."
+msgstr ""
+"当smartdns异常时生成coredump文件,coredump文件在/tmp/smartdns.xxx.core."
 
-msgid "Domain TTL Min"
-msgstr "域名TTL最小值"
+msgid "Grant access to LuCI app smartdns"
+msgstr "授予访问 LuCI 应用 smartdns 的权限"
 
-msgid "Minimum TTL for all domain result."
-msgstr "设置所有域名的TTL最小值"
+msgid "HTTP Host"
+msgstr "HTTP主机"
 
-msgid "Domain TTL Max"
-msgstr "域名TTL最大值"
+msgid "IP Blacklist"
+msgstr "IP黑名单"
 
-msgid "Maximum TTL for all domain result."
-msgstr "设置所有域名的TTL最大值"
+msgid "IP Blacklist Filtering"
+msgstr "IP黑名单过滤"
 
-msgid "Maximum Reply TTL for all domain result."
-msgstr "设置返回给客户端的TTL最大值"
+msgid "IPV6 Server"
+msgstr "IPV6服务器"
 
-msgid "smartdns custom settings"
-msgstr "smartdns 自定义设置,具体配置参数参考指导"
+msgid "If you like this software, please buy me a cup of coffee."
+msgstr "如果本软件对你有帮助,请给作者加个蛋。"
 
-msgid "Second Server Settings"
-msgstr "第二DNS服务器"
+msgid "Local Port"
+msgstr "本地端口"
 
-msgid "Enable or disable second DNS server."
-msgstr "是否启用第二DNS服务器。"
+msgid "Maximum TTL for all domain result."
+msgstr "所有域名的最大 TTL 值。"
 
-msgid "Skip Speed Check"
-msgstr "跳过测速"
+msgid "Minimum TTL for all domain result."
+msgstr "所有域名的最小 TTL 值。"
 
-msgid "Do not check speed."
-msgstr "禁用测速。"
+msgid "NOT RUNNING"
+msgstr "未运行"
 
-msgid "Server Group"
-msgstr "服务器组"
+msgid "No check certificate"
+msgstr "停用证书校验"
 
 msgid "Query DNS through specific dns server group, such as office, home."
 msgstr "使用指定服务器组查询,比如office, home。"
 
-msgid "Skip Address Rules"
-msgstr "跳过address规则"
+msgid "RUNNING"
+msgstr "运行中"
 
-msgid "Skip address rules."
-msgstr "跳过address规则。"
+msgid "Reply Domain TTL Max"
+msgstr "回应的域名TTL最大值"
 
-msgid "Skip Nameserver Rule"
-msgstr "跳过Nameserver规则"
+msgid "Reply maximum TTL for all domain result."
+msgstr "设置返回给客户端的域名TTL最大值。"
 
-msgid "Skip nameserver rules."
-msgstr "跳过Nameserver规则。"
+msgid "Resolve Local Hostnames"
+msgstr "解析本地主机名"
 
-msgid "Skip Ipset Rule"
-msgstr "跳过ipset规则"
+msgid "Resolve local hostnames by reading Dnsmasq lease file."
+msgstr "读取Dnsmasq的租约文件解析本地主机名。"
 
-msgid "Skip ipset rules."
-msgstr "跳过ipset规则。"
+msgid "Second Server Settings"
+msgstr "第二DNS服务器"
 
-msgid "Skip SOA Address Rule"
-msgstr "跳过address SOA(#)规则"
+msgid "Serve expired"
+msgstr "缓存过期服务"
 
-msgid "Skip SOA address rules."
-msgstr "跳过address SOA(#)规则。"
+msgid "Server Group"
+msgstr "服务器组"
 
-msgid "Skip Dualstack Selection"
-msgstr "跳过双栈优选"
+msgid "Server Name"
+msgstr "服务器名称"
 
-msgid "Skip Dualstack Selection."
-msgstr "跳过双栈优选。"
+msgid "Set Specific domain ip address."
+msgstr "设置指定域名的IP地址。"
+
+msgid "Set Specific ip blacklist."
+msgstr "设置指定的 IP 黑名单列表。"
+
+msgid "Set TLS hostname to verify."
+msgstr "设置校验TLS主机名。"
+
+msgid ""
+"Set the HTTP host used for the query. Use this parameter when the host of "
+"the URL address is an IP address."
+msgstr "设置查询时使用的HTTP主机,当URL地址的host是IP地址时,使用此参数。"
+
+msgid "Sets the server name indication for query."
+msgstr "设置查询时使用的服务器SNI名称。"
+
+msgid "Settings"
+msgstr "设置"
+
+msgid "Skip Address Rules"
+msgstr "跳过address规则"
 
 msgid "Skip Cache"
 msgstr "跳过cache"
@@ -184,119 +222,123 @@ msgstr "跳过cache"
 msgid "Skip Cache."
 msgstr "跳过cache。"
 
-msgid "Upstream Servers"
-msgstr "上游服务器"
-
-msgid "Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS servers, including multiple foreign DNS servers."
-msgstr "上游DNS服务器列表,支持UDP,TCP协议,请配置多个上游DNS服务器,包括多个国内外服务器"
-
-msgid "DNS Server Name"
-msgstr "DNS服务器名称"
-
-msgid "port"
-msgstr "端口"
+msgid "Skip Dualstack Selection"
+msgstr "跳过双栈优选"
 
-msgid "DNS Server port"
-msgstr "DNS服务器端口"
+msgid "Skip Dualstack Selection."
+msgstr "跳过双栈优选。"
 
-msgid "DNS Server ip"
-msgstr "DNS服务器IP"
+msgid "Skip Ipset Rule"
+msgstr "跳过ipset规则"
 
-msgid "type"
-msgstr "类型"
+msgid "Skip Nameserver Rule"
+msgstr "跳过Nameserver规则"
 
-msgid "DNS Server type"
-msgstr "协议类型"
+msgid "Skip SOA Address Rule"
+msgstr "跳过address SOA(#)规则"
 
-msgid "Domain Address"
-msgstr "域名地址"
+msgid "Skip SOA address rules."
+msgstr "跳过address SOA(#)规则。"
 
-msgid "TLS Hostname Verify"
-msgstr "校验TLS主机名"
+msgid "Skip Speed Check"
+msgstr "跳过测速"
 
-msgid "Set TLS hostname to verify."
-msgstr "设置校验TLS主机名。"
+msgid "Skip address rules."
+msgstr "跳过address规则。"
 
-msgid "No check certificate"
-msgstr "停用证书校验"
+msgid "Skip ipset rules."
+msgstr "跳过ipset规则。"
 
-msgid "Do not check certificate."
-msgstr "不校验证书的合法性。"
+msgid "Skip nameserver rules."
+msgstr "跳过Nameserver规则。"
 
-msgid "TLS SNI name"
-msgstr "TLS SNI名称"
+msgid "SmartDNS"
+msgstr "SmartDNS"
 
-msgid "HTTP Host"
-msgstr "HTTP主机"
+msgid "SmartDNS Server"
+msgstr "SmartDNS 服务器"
 
-msgid "Sets the server name indication for query."
-msgstr "设置查询时使用的服务器SNI名称。"
+msgid ""
+"SmartDNS is a local high-performance DNS server, supports finding fastest "
+"IP, supports ad filtering, and supports avoiding DNS poisoning."
+msgstr "SmartDNS是一个本地高性能DNS服务器,支持返回最快IP,支持广告过滤。"
 
-msgid "Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address."
-msgstr "设置查询时使用的HTTP主机,当URL地址的host是IP地址时,使用此参数。"
+msgid "SmartDNS official website"
+msgstr "SmartDNS官方网站"
 
-msgid "Server Group"
-msgstr "服务器组"
+msgid "Smartdns local server port"
+msgstr "SmartDNS本地服务端口"
 
-msgid "DNS Server group belongs to, used with nameserver, such as office, home."
-msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。"
+msgid "Smartdns server name"
+msgstr "SmartDNS的服务器名称,默认为smartdns,留空为主机名"
 
-msgid "IP Blacklist Filtering"
-msgstr "IP黑名单过滤"
+msgid ""
+"Specify an IP address to return for any host in the given domains, Queries "
+"in the domains are never forwarded and always replied to with the specified "
+"IP address which may be IPv4 or IPv6."
+msgstr ""
+"配置特定域名返回特定的IP地址,域名查询将不到上游服务器请求,直接返回配置的IP"
+"地址,可用于广告屏蔽。"
 
-msgid "Anti Answer Forgery"
-msgstr "反回答伪造"
+msgid "TCP Server"
+msgstr "TCP服务器"
 
-msgid "Anti answer forgery, if DNS does not work properly after enabling, please turn off this feature"
-msgstr "反回答伪造,如果启用后DNS工作不正常,请关闭此功能。"
+msgid "TLS Hostname Verify"
+msgstr "校验TLS主机名"
 
-msgid "Filtering IP with blacklist"
-msgstr "使用IP黑名单过滤"
+msgid "TLS SNI name"
+msgstr "TLS SNI名称"
 
 msgid "TLS SPKI Pinning"
 msgstr "TLS SPKI 指纹"
 
-msgid "Used to verify the validity of the TLS server, The value is Base64 encoded SPKI fingerprint, leaving blank to indicate that the validity of TLS is not verified."
-msgstr "用于校验TLS服务器的有效性,数值为Base64编码的SPKI指纹, 留空表示不验证TLS的合法性"
-
-msgid "Additional Server Args"
-msgstr "额外的服务器参数"
+msgid "TTL for all domain result."
+msgstr "设置所有域名的 TTL 值。"
 
-msgid "Additional Args for upstream dns servers"
-msgstr "额外的上游DNS服务器参数"
+msgid "Technical Support"
+msgstr "技术支持"
 
-msgid "Upstream DNS Server Configuration"
-msgstr "上游DNS服务器配置"
+msgid "Upstream Servers"
+msgstr "上游服务器"
 
-msgid "Set Specific domain ip address."
-msgstr "指定特定域名的IP地址"
+msgid ""
+"Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS "
+"servers, including multiple foreign DNS servers."
+msgstr ""
+"上游 DNS 服务器,支持 UDP,TCP 协议。请配置多个上游 DNS 服务器,包括多个国内"
+"外服务器。"
 
-msgid "Specify an IP address to return for any host in the given domains, Queries in the domains are never forwarded and always replied to with the specified IP address which may be IPv4 or IPv6."
-msgstr "配置特定域名返回特定的IP地址,域名查询将不到上游服务器请求,直接返回配置的IP地址,可用于广告屏蔽。"
+msgid ""
+"Used to verify the validity of the TLS server, The value is Base64 encoded "
+"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not "
+"verified."
+msgstr ""
+"用于校验 TLS 服务器的有效性,数值为 Base64 编码的 SPKI 指纹,留空表示不验证 "
+"TLS 的合法性。"
 
-msgid "IP Blacklist"
-msgstr "IP黑名单"
+msgid "https"
+msgstr "https"
 
-msgid "Set Specific ip blacklist."
-msgstr "设置IP黑名单列表"
+msgid "ip"
+msgstr "ip"
 
-msgid "Configure IP blacklists that will be filtered from the results of specific DNS server."
-msgstr "配置需要从指定域名服务器结果过滤的IP黑名单。"
+msgid "open website"
+msgstr "打开网站"
 
-msgid "Technical Support"
-msgstr "技术支持"
+msgid "port"
+msgstr "端口"
 
-msgid "If you like this software, please buy me a cup of coffee."
-msgstr "如果本软件对你有帮助,请给作者加个蛋。"
+msgid "smartdns custom settings"
+msgstr "smartdns 自定义设置,具体配置参数参考指导"
 
-msgid "SmartDNS official website"
-msgstr "SmartDNS官方网站"
+msgid "tcp"
+msgstr "tcp"
 
-msgid "open website"
-msgstr "打开网站"
+msgid "tls"
+msgstr "tls"
 
-msgid "Donate to smartdns"
-msgstr "捐助smartdns项目"
+msgid "type"
+msgstr "类型"
 
-msgid "Donate"
-msgstr "捐助"
+msgid "udp"
+msgstr "udp"

+ 35 - 12
package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua

@@ -46,8 +46,8 @@ o.rempty      = false
 
 ---- Port
 o = s:taboption("settings", Value, "port", translate("Local Port"), translate("Smartdns local server port"))
-o.placeholder = 6053
-o.default     = 6053
+o.placeholder = 53
+o.default     = 53
 o.datatype    = "port"
 o.rempty      = false
 
@@ -92,19 +92,42 @@ o.cfgvalue    = function(...)
     return Flag.cfgvalue(...) or "0"
 end
 
----- Redirect
-o = s:taboption("settings", ListValue, "redirect", translate("Redirect"), translate("SmartDNS redirect mode"))
-o.placeholder = "none"
-o:value("none", translate("none"))
-o:value("dnsmasq-upstream", translate("Run as dnsmasq upstream server"))
-o:value("redirect", translate("Redirect 53 port to SmartDNS"))
-o.default     = "none"
-o.rempty      = false
-
 ---- cache-size
 o = s:taboption("settings", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size"))
 o.rempty      = true
 
+-- cache-size
+o = s:taboption("settings", Flag, "resolve_local_hostnames", translate("Resolve Local Hostnames"), translate("Resolve local hostnames by reading Dnsmasq lease file."));
+o.rmempty     = false
+o.default     = o.enabled
+o.cfgvalue    = function(...)
+    return Flag.cfgvalue(...) or "1"
+end
+
+-- 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.rmempty     = false
+o.default     = o.enabled
+o.cfgvalue    = function(...)
+    return Flag.cfgvalue(...) or "0"
+end
+
+-- Force AAAA SOA
+o = s:taboption("settings", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."));
+o.rmempty     = false
+o.default     = o.enabled
+o.cfgvalue    = function(...)
+    return Flag.cfgvalue(...) or "0"
+end
+
+-- Force HTTPS SOA
+o = s:taboption("settings", Flag, "force_https_soa", translate("Force HTTPS SOA"), translate("Force HTTPS SOA."));
+o.rmempty     = false
+o.default     = o.enabled
+o.cfgvalue    = function(...)
+    return Flag.cfgvalue(...) or "0"
+end
+
 ---- rr-ttl
 o = s:taboption("settings", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result."))
 o.rempty      = true
@@ -121,7 +144,7 @@ o = s:taboption("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), tr
 o.rempty      = true
 
 ---- rr-ttl-reply-max
-o = s:taboption("settings", Value, "rr_ttl_reply_max", translate("Domain TTL Max"), translate("Maximum Reply TTL for all domain result."))
+o = s:taboption("settings", Value, "rr_ttl_reply_max", translate("Domain TTL Max"), translate("Reply maximum TTL for all domain result."))
 o.rempty      = true
 
 ---- second dns server

+ 0 - 17
package/luci-compat/files/luci/view/smartdns/smartdns_status.htm

@@ -6,23 +6,6 @@ XHR.poll(3, '<%=luci.dispatcher.build_url("admin", "services", "smartdns", "stat
 			var links = "";
 			if (data.running) {
 				links = '<b><font color=green>SmartDNS - <%:RUNNING%></font></b></em>';
-				if (data.redirect) {
-					if (data.redirect == 1) {
-						if (data.ipv4_works == 0) {
-							links += "<br></br><b><font color=red><%:IPV4 53 Port Redirect Failure%></font></b>"
-						}
-						
-						if (data.ipv6_works != 2) {
-							if (data.ipv6_works == 0) {
-								links += "<br></br><b><font color=red><%:IPV6 53 Port Redirect Failure%></font></b>"
-							}
-						}
-					} else if (data.redirect == 2) {
-						if (data.dnsmasq_forward == 0) {
-							links += "<br></br><b><font color=red><%:Dnsmasq Forwared To Smartdns Failure%></font></b>"
-						}
-					}
-				}
 			} else {
 				links = '<b><font color=red>SmartDNS - <%:NOT RUNNING%></font></b>';
 			}

+ 232 - 208
package/luci/files/luci/i18n/smartdns.zh-cn.po

@@ -1,320 +1,344 @@
-msgid ""
-msgstr "Content-Type: text/plain; charset=UTF-8\n"
 
-msgid "SmartDNS"
-msgstr "SmartDNS"
+msgid "Additional Args for upstream dns servers"
+msgstr "额外的上游 DNS 服务器参数"
 
-msgid "SmartDNS is a local high-performance DNS server"
-msgstr "SmartDNS是一个本地高性能DNS服务器"
+msgid "Additional Server Args"
+msgstr "额外的服务器参数"
 
-msgid "SmartDNS Server"
-msgstr "SmartDNS 服务器"
+msgid "Advanced Settings"
+msgstr "高级设置"
 
-msgid "SmartDNS is a local high-performance DNS server, supports finding fastest IP, supports ad filtering, and supports avoiding DNS poisoning."
-msgstr "SmartDNS是一个本地高性能DNS服务器,支持返回最快IP,支持广告过滤。"
+msgid ""
+"Attempts to serve old responses from cache with a TTL of 0 in the response "
+"without waiting for the actual resolution to finish."
+msgstr "查询性能优化,有请求时尝试回应TTL为0的过期记录,以避免查询等待。"
 
-msgid "Custom Settings"
-msgstr "自定义设置"
+msgid "Automatically Set Dnsmasq"
+msgstr "自动设置Dnsmasq"
 
-msgid "General Settings"
-msgstr "基本设置"
+msgid "Automatically set as upstream of dnsmasq when port changes."
+msgstr "自动设置为Dnsmasq的上游服务器"
 
-msgid "Settings"
-msgstr "设置"
+msgid "Cache Size"
+msgstr "缓存大小"
 
-msgid "Advanced Settings"
-msgstr "高级设置"
+msgid "Collecting data ..."
+msgstr "正在收集数据..."
 
-msgid "RUNNING"
-msgstr "运行中"
+msgid ""
+"Configure IP blacklists that will be filtered from the results of specific "
+"DNS server."
+msgstr "配置需要从指定域名服务器结果过滤的IP黑名单。"
 
-msgid "NOT RUNNING"
-msgstr "未运行"
+msgid "Custom Settings"
+msgstr "自定义设置"
 
-msgid "Generate Coredump"
-msgstr "生成coredump"
+msgid "DNS Server Name"
+msgstr "DNS服务器名称"
 
-msgid "Generate Coredump file when smartdns crash, coredump file is located at /tmp/smartdns.xxx.core."
-msgstr "当smartdns异常时生成coredump文件,coredump文件在/tmp/smartdns.xxx.core."
+msgid ""
+"DNS Server group belongs to, used with nameserver, such as office, home."
+msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。"
 
-msgid "Server Name"
-msgstr "服务器名称"
+msgid "DNS Server ip"
+msgstr "DNS服务器IP"
 
-msgid "Smartdns server name"
-msgstr "SmartDNS的服务器名称,默认为smartdns,留空为主机名"
+msgid "DNS Server port"
+msgstr "DNS服务器端口"
 
-msgid "SmartDNS is a local dns server to find fastest ip."
-msgstr "本地高性能服务器,优化网络访问性能。"
+msgid "DNS Server type"
+msgstr "协议类型"
 
-msgid "Enable or disable smartdns server"
-msgstr "启用或禁用SmartDNS服务"
+msgid "DNS domain result cache size"
+msgstr "缓存DNS的结果,缓存大小,配置零则不缓存"
 
-msgid "Local Port"
-msgstr "本地端口"
+msgid "Do not check certificate."
+msgstr "不校验证书的合法性。"
 
-msgid "Smartdns local server port"
-msgstr "SmartDNS本地服务端口"
+msgid "Do not check speed."
+msgstr "禁用测速。"
 
-msgid "IPV4 53 Port Redirect Failure"
-msgstr "IPV4 53端口重定向失败"
+msgid "Domain Address"
+msgstr "域名地址"
 
-msgid "IPV6 53 Port Redirect Failure"
-msgstr "IPV6 53端口重定向失败"
+msgid "Domain TTL"
+msgstr "域名TTL"
 
-msgid "Dnsmasq Forwared To Smartdns Failure"
-msgstr "重定向dnsmasq到smartdns失败"
+msgid "Domain TTL Max"
+msgstr "域名TTL最大值"
 
-msgid "TCP Server"
-msgstr "TCP服务器"
+msgid "Domain TTL Min"
+msgstr "域名TTL最小值"
 
-msgid "Enable TCP DNS Server"
-msgstr "启用TCP服务器"
+msgid "Domain prefetch"
+msgstr "域名预加载"
 
-msgid "IPV6 Server"
-msgstr "IPV6服务器"
+msgid "Donate"
+msgstr "捐助"
 
-msgid "Enable IPV6 DNS Server"
-msgstr "启用IPV6服务器"
+msgid "Donate to smartdns"
+msgstr "捐助smartdns项目"
 
 msgid "Dual-stack IP Selection"
 msgstr "双栈IP优选"
 
+msgid "Enable"
+msgstr "启用"
+
 msgid "Enable IP selection between IPV4 and IPV6"
-msgstr "启用或禁用IPV4,IPV6间的IP优选策略。"
+msgstr "启用 IPV4 和 IPV6 间的 IP 优选策略"
 
-msgid "Domain prefetch"
-msgstr "域名预加载"
+msgid "Enable IPV6 DNS Server"
+msgstr "启用IPV6服务器"
+
+msgid "Enable TCP DNS Server"
+msgstr "启用TCP服务器"
 
 msgid "Enable domain prefetch, accelerate domain response speed."
 msgstr "启用域名预加载,加速域名响应速度。"
 
-msgid "Serve expired"
-msgstr "缓存过期服务"
-
-msgid "Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."
-msgstr "查询性能优化,有请求时尝试回应TTL为0的过期记录,以避免查询等待。"
-
-msgid "Redirect"
-msgstr "重定向"
+msgid "Enable or disable second DNS server."
+msgstr "是否启用第二DNS服务器。"
 
-msgid "SmartDNS redirect mode"
-msgstr "SmartDNS 重定向模式"
+msgid "Enable or disable smartdns server"
+msgstr "启用或禁用SmartDNS服务"
 
-msgid "Run as dnsmasq upstream server"
-msgstr "作为dnsmasq的上游服务器"
+msgid "Filtering IP with blacklist"
+msgstr "使用IP黑名单过滤"
 
-msgid "Redirect 53 port to SmartDNS"
-msgstr "重定向53端口到SmartDNS"
+msgid "Force AAAA SOA"
+msgstr "停用IPV6地址解析"
 
-msgid "Cache Size"
-msgstr "缓存大小"
+msgid "Force AAAA SOA."
+msgstr "停用IPV6地址解析。"
 
-msgid "Resolve Local Hostnames"
-msgstr "本地主机名解析"
+msgid "Force HTTPS SOA"
+msgstr "停用HTTPS地址解析"
 
-msgid "Resolve local hostnames by reading Dnsmasq lease file"
-msgstr "读取Dnsmasq的DHCP Lease文件解析本地主机名"
+msgid "Force HTTPS SOA."
+msgstr "停用HTTPS地址解析。"
 
-msgid "DNS domain result cache size"
-msgstr "缓存DNS的结果,缓存大小,配置零则不缓存(单位:条)"
+msgid "General Settings"
+msgstr "常规设置"
 
-msgid "Domain TTL"
-msgstr "域名TTL"
+msgid "Generate Coredump"
+msgstr "生成coredump"
 
-msgid "TTL for all domain result."
-msgstr "设置所有域名的TTL值(单位:秒,下同)"
+msgid ""
+"Generate Coredump file when smartdns crash, coredump file is located at /tmp/"
+"smartdns.xxx.core."
+msgstr ""
+"当smartdns异常时生成coredump文件,coredump文件在/tmp/smartdns.xxx.core."
 
-msgid "Domain TTL Min"
-msgstr "域名TTL最小值"
+msgid "Grant access to LuCI app smartdns"
+msgstr "授予访问 LuCI 应用 smartdns 的权限"
 
-msgid "Minimum TTL for all domain result."
-msgstr "设置所有域名的TTL最小值"
+msgid "HTTP Host"
+msgstr "HTTP主机"
 
-msgid "Domain TTL Max"
-msgstr "域名TTL最大值"
+msgid "IP Blacklist"
+msgstr "IP黑名单"
 
-msgid "Maximum TTL for all domain result."
-msgstr "设置所有域名的TTL最大值"
+msgid "IP Blacklist Filtering"
+msgstr "IP黑名单过滤"
 
-msgid "Maximum Reply TTL for all domain result."
-msgstr "设置返回给客户端的TTL最大值"
+msgid "IPV6 Server"
+msgstr "IPV6服务器"
 
-msgid "smartdns custom settings"
-msgstr "smartdns 自定义设置,具体配置参数参考指导"
+msgid "If you like this software, please buy me a cup of coffee."
+msgstr "如果本软件对你有帮助,请给作者加个蛋。"
 
-msgid "Second Server Settings"
-msgstr "第二DNS服务器"
+msgid "Local Port"
+msgstr "本地端口"
 
-msgid "Enable or disable second DNS server."
-msgstr "是否启用第二DNS服务器。"
+msgid "Maximum TTL for all domain result."
+msgstr "所有域名的最大 TTL 值。"
 
-msgid "Skip Speed Check"
-msgstr "跳过测速"
+msgid "Minimum TTL for all domain result."
+msgstr "所有域名的最小 TTL 值。"
 
-msgid "Do not check speed."
-msgstr "禁用测速。"
+msgid "NOT RUNNING"
+msgstr "未运行"
 
-msgid "Server Group"
-msgstr "服务器组"
+msgid "No check certificate"
+msgstr "停用证书校验"
 
 msgid "Query DNS through specific dns server group, such as office, home."
 msgstr "使用指定服务器组查询,比如office, home。"
 
-msgid "Skip Address Rules"
-msgstr "跳过address规则"
+msgid "RUNNING"
+msgstr "运行中"
 
-msgid "Skip address rules."
-msgstr "跳过address规则。"
+msgid "Reply Domain TTL Max"
+msgstr "回应的域名TTL最大值"
 
-msgid "Skip Nameserver Rule"
-msgstr "跳过Nameserver规则"
+msgid "Reply maximum TTL for all domain result."
+msgstr "设置返回给客户端的域名TTL最大值。"
 
-msgid "Skip nameserver rules."
-msgstr "跳过Nameserver规则。"
+msgid "Resolve Local Hostnames"
+msgstr "解析本地主机名"
 
-msgid "Skip Ipset Rule"
-msgstr "跳过ipset规则"
+msgid "Resolve local hostnames by reading Dnsmasq lease file."
+msgstr "读取Dnsmasq的租约文件解析本地主机名。"
 
-msgid "Skip ipset rules."
-msgstr "跳过ipset规则。"
+msgid "Second Server Settings"
+msgstr "第二DNS服务器"
 
-msgid "Skip SOA Address Rule"
-msgstr "跳过address SOA(#)规则"
+msgid "Serve expired"
+msgstr "缓存过期服务"
 
-msgid "Skip SOA address rules."
-msgstr "跳过address SOA(#)规则。"
+msgid "Server Group"
+msgstr "服务器组"
 
-msgid "Skip Dualstack Selection"
-msgstr "跳过双栈优选"
+msgid "Server Name"
+msgstr "服务器名称"
 
-msgid "Skip Dualstack Selection."
-msgstr "跳过双栈优选。"
+msgid "Set Specific domain ip address."
+msgstr "设置指定域名的IP地址。"
 
-msgid "Skip Cache"
-msgstr "跳过cache"
+msgid "Set Specific ip blacklist."
+msgstr "设置指定的 IP 黑名单列表。"
 
-msgid "Skip Cache."
-msgstr "跳过cache。"
+msgid "Set TLS hostname to verify."
+msgstr "设置校验TLS主机名。"
 
-msgid "Force AAAA SOA"
-msgstr "停用IPV6地址解析"
+msgid ""
+"Set the HTTP host used for the query. Use this parameter when the host of "
+"the URL address is an IP address."
+msgstr "设置查询时使用的HTTP主机,当URL地址的host是IP地址时,使用此参数。"
 
-msgid "Force HTTPS SOA."
-msgstr "停用HTTPS解析。"
+msgid "Sets the server name indication for query."
+msgstr "设置查询时使用的服务器SNI名称。"
 
-msgid "Upstream Servers"
-msgstr "上游服务器"
+msgid "Settings"
+msgstr "设置"
 
-msgid "Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS servers, including multiple foreign DNS servers."
-msgstr "上游DNS服务器列表,支持UDP,TCP协议,请配置多个上游DNS服务器,包括多个国内外服务器"
+msgid "Skip Address Rules"
+msgstr "跳过address规则"
 
-msgid "DNS Server Name"
-msgstr "DNS服务器名称"
+msgid "Skip Cache"
+msgstr "跳过cache"
 
-msgid "port"
-msgstr "端口"
+msgid "Skip Cache."
+msgstr "跳过cache。"
 
-msgid "DNS Server port"
-msgstr "DNS服务器端口"
+msgid "Skip Dualstack Selection"
+msgstr "跳过双栈优选"
 
-msgid "DNS Server ip"
-msgstr "DNS服务器IP"
+msgid "Skip Dualstack Selection."
+msgstr "跳过双栈优选。"
 
-msgid "type"
-msgstr "类型"
+msgid "Skip Ipset Rule"
+msgstr "跳过ipset规则"
 
-msgid "DNS Server type"
-msgstr "协议类型"
+msgid "Skip Nameserver Rule"
+msgstr "跳过Nameserver规则"
 
-msgid "Domain Address"
-msgstr "域名地址"
+msgid "Skip SOA Address Rule"
+msgstr "跳过address SOA(#)规则"
 
-msgid "TLS Hostname Verify"
-msgstr "校验TLS主机名"
+msgid "Skip SOA address rules."
+msgstr "跳过address SOA(#)规则。"
 
-msgid "Set TLS hostname to verify."
-msgstr "设置校验TLS主机名。"
+msgid "Skip Speed Check"
+msgstr "跳过测速"
 
-msgid "No check certificate"
-msgstr "停用证书校验"
+msgid "Skip address rules."
+msgstr "跳过address规则。"
 
-msgid "Do not check certificate."
-msgstr "不校验证书的合法性。"
+msgid "Skip ipset rules."
+msgstr "跳过ipset规则。"
 
-msgid "TLS SNI name"
-msgstr "TLS SNI名称"
+msgid "Skip nameserver rules."
+msgstr "跳过Nameserver规则。"
 
-msgid "HTTP Host"
-msgstr "HTTP主机"
+msgid "SmartDNS"
+msgstr "SmartDNS"
 
-msgid "Sets the server name indication for query."
-msgstr "设置查询时使用的服务器SNI名称。"
+msgid "SmartDNS Server"
+msgstr "SmartDNS 服务器"
 
-msgid "Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address."
-msgstr "设置查询时使用的HTTP主机,当URL地址的host是IP地址时,使用此参数。"
+msgid ""
+"SmartDNS is a local high-performance DNS server, supports finding fastest "
+"IP, supports ad filtering, and supports avoiding DNS poisoning."
+msgstr "SmartDNS是一个本地高性能DNS服务器,支持返回最快IP,支持广告过滤。"
 
-msgid "Server Group"
-msgstr "服务器组"
+msgid "SmartDNS official website"
+msgstr "SmartDNS官方网站"
 
-msgid "DNS Server group belongs to, used with nameserver, such as office, home."
-msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。"
+msgid "Smartdns local server port"
+msgstr "SmartDNS本地服务端口"
 
-msgid "IP Blacklist Filtering"
-msgstr "IP黑名单过滤"
+msgid "Smartdns server name"
+msgstr "SmartDNS的服务器名称,默认为smartdns,留空为主机名"
 
-msgid "Anti Answer Forgery"
-msgstr "反回答伪造"
+msgid ""
+"Specify an IP address to return for any host in the given domains, Queries "
+"in the domains are never forwarded and always replied to with the specified "
+"IP address which may be IPv4 or IPv6."
+msgstr ""
+"配置特定域名返回特定的IP地址,域名查询将不到上游服务器请求,直接返回配置的IP"
+"地址,可用于广告屏蔽。"
 
-msgid "Anti answer forgery, if DNS does not work properly after enabling, please turn off this feature"
-msgstr "反回答伪造,如果启用后DNS工作不正常,请关闭此功能。"
+msgid "TCP Server"
+msgstr "TCP服务器"
 
-msgid "Filtering IP with blacklist"
-msgstr "使用IP黑名单过滤"
+msgid "TLS Hostname Verify"
+msgstr "校验TLS主机名"
+
+msgid "TLS SNI name"
+msgstr "TLS SNI名称"
 
 msgid "TLS SPKI Pinning"
 msgstr "TLS SPKI 指纹"
 
-msgid "Used to verify the validity of the TLS server, The value is Base64 encoded SPKI fingerprint, leaving blank to indicate that the validity of TLS is not verified."
-msgstr "用于校验TLS服务器的有效性,数值为Base64编码的SPKI指纹, 留空表示不验证TLS的合法性"
-
-msgid "Additional Server Args"
-msgstr "额外的服务器参数"
+msgid "TTL for all domain result."
+msgstr "设置所有域名的 TTL 值。"
 
-msgid "Additional Args for upstream dns servers"
-msgstr "额外的上游DNS服务器参数"
+msgid "Technical Support"
+msgstr "技术支持"
 
-msgid "Upstream DNS Server Configuration"
-msgstr "上游DNS服务器配置"
+msgid "Upstream Servers"
+msgstr "上游服务器"
 
-msgid "Set Specific domain ip address."
-msgstr "指定特定域名的IP地址"
+msgid ""
+"Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS "
+"servers, including multiple foreign DNS servers."
+msgstr ""
+"上游 DNS 服务器,支持 UDP,TCP 协议。请配置多个上游 DNS 服务器,包括多个国内"
+"外服务器。"
 
-msgid "Specify an IP address to return for any host in the given domains, Queries in the domains are never forwarded and always replied to with the specified IP address which may be IPv4 or IPv6."
-msgstr "配置特定域名返回特定的IP地址,域名查询将不到上游服务器请求,直接返回配置的IP地址,可用于广告屏蔽。"
+msgid ""
+"Used to verify the validity of the TLS server, The value is Base64 encoded "
+"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not "
+"verified."
+msgstr ""
+"用于校验 TLS 服务器的有效性,数值为 Base64 编码的 SPKI 指纹,留空表示不验证 "
+"TLS 的合法性。"
 
-msgid "IP Blacklist"
-msgstr "IP黑名单"
+msgid "https"
+msgstr "https"
 
-msgid "Set Specific ip blacklist."
-msgstr "设置IP黑名单列表"
+msgid "ip"
+msgstr "ip"
 
-msgid "Configure IP blacklists that will be filtered from the results of specific DNS server."
-msgstr "配置需要从指定域名服务器结果过滤的IP黑名单。"
+msgid "open website"
+msgstr "打开网站"
 
-msgid "Technical Support"
-msgstr "技术支持"
+msgid "port"
+msgstr "端口"
 
-msgid "If you like this software, please buy me a cup of coffee."
-msgstr "如果本软件对你有帮助,请给作者加个蛋。"
+msgid "smartdns custom settings"
+msgstr "smartdns 自定义设置,具体配置参数参考指导"
 
-msgid "SmartDNS official website"
-msgstr "SmartDNS官方网站"
+msgid "tcp"
+msgstr "tcp"
 
-msgid "open website"
-msgstr "打开网站"
+msgid "tls"
+msgstr "tls"
 
-msgid "Donate to smartdns"
-msgstr "捐助smartdns项目"
+msgid "type"
+msgstr "类型"
 
-msgid "Donate"
-msgstr "捐助"
+msgid "udp"
+msgstr "udp"

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

@@ -4,8 +4,6 @@
 		"read": {
 			"file": {
 				"/etc/smartdns/*": [ "read" ],
-				"/usr/sbin/iptables -t nat -nL PREROUTING": [ "exec" ],
-				"/usr/sbin/ip6tables -t nat -nL PREROUTING": [ "exec" ],
 				"/usr/sbin/smartdns": [ "exec" ]
 			},
 			"ubus": {

+ 444 - 500
package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js

@@ -17,503 +17,447 @@
  */
 
 
-'use strict';
-'require fs';
-'require uci';
-'require form';
-'require rpc';
-
-var conf = 'smartdns';
-var callServiceList = rpc.declare({
-	object: 'service',
-	method: 'list',
-	params: ['name'],
-	expect: { '': {} }
-});
-
-function getServiceStatus() {
-	return L.resolveDefault(callServiceList(conf), {})
-		.then(function (res) {
-			var isrunning = false;
-			try {
-				isrunning = res[conf]['instances']['smartdns']['running'];
-			} catch (e) { }
-			return isrunning;
-		});
-}
-
-function getIPTablesRedirect() {
-	return fs.exec('/usr/sbin/iptables', ['-t', 'nat', '-nL', 'PREROUTING']).then(function (res) {
-		if (res.code === 0) {
-			return res.stdout.trim();
-		} else {
-			return "";
-		}
-	}).catch(function (err) {
-		return "";
-	});
-}
-
-function getIP6TablesRedirect() {
-	return fs.exec('/usr/sbin/ip6tables', ['-t', 'nat', '-nL', 'PREROUTING']).then(function (res) {
-		if (res.code === 0) {
-			return res.stdout.trim();
-		} else {
-			return "";
-		}
-	}).catch(function (err) {
-		return "";
-	});;
-}
-
-function smartdnsServiceStatus() {
-	return Promise.all([
-		getServiceStatus(),
-		getIPTablesRedirect(),
-		getIP6TablesRedirect()
-	]);
-}
-
-function smartdnsRenderStatus(res) {
-	var renderHTML = "";
-	var isRunning = res[0];
-	var ipt = res[1];
-	var ip6t = res[2];
-
-	var serverPort = uci.get_first('smartdns', 'smartdns', 'port');
-	var redirectMode = uci.get_first('smartdns', 'smartdns', 'redirect');
-	var ipv6Enabled = uci.get_first('smartdns', 'smartdns', 'ipv6_server');
-
-	if (isRunning) {
-		renderHTML += "<span style=\"color:green;font-weight:bold\">SmartDNS - " + _("RUNNING") + "</span>";
-	} else {
-		renderHTML += "<span style=\"color:red;font-weight:bold\">SmartDNS - " + _("NOT RUNNING") + "</span>";
-		return renderHTML;
-	}
-
-	if (redirectMode === "dnsmasq-upstream") {
-		var matchLine = "127.0.0.1#" + serverPort;
-		var dnsmasqServer = uci.get_first('dhcp', 'dnsmasq', 'server') || "";
-
-		if (dnsmasqServer.indexOf(matchLine) < 0) {
-			renderHTML += "<br /><span style=\"color:red;font-weight:bold\">" + _("Dnsmasq Forwared To Smartdns Failure") + "</span>";
-		}
-	} else if (redirectMode === "redirect") {
-		var redirectRules = (ipt || '').split(/\n/).filter(function (rule) {
-			return rule.match(/REDIRECT/) && rule.match(/dpt:53/) && rule.match("ports " + serverPort);
-		});
-
-		if (redirectRules.length <= 0) {
-			renderHTML += "<br /><span style=\"color:red;font-weight:bold\">" + _("IPV4 53 Port Redirect Failure") + "</span>";
-			if (ipv6Enabled) {
-				var redirectRules = (ip6t || '').split(/\n/).filter(function (rule) {
-					return rule.match(/REDIRECT/) && rule.match(/dpt:53/) && rule.match("ports " + serverPort);
-				});
-				if (redirectRules.length <= 0) {
-					renderHTML += "<br /><span style=\"color:red;font-weight:bold\">" + _("IPV6 53 Port Redirect Failure") + "</span>";
-				}
-			}
-		}
-	}
-
-	return renderHTML;
-}
-
-return L.view.extend({
-	load: function () {
-		return Promise.all([
-			uci.load('smartdns'),
-			uci.load('dhcp')
-		]);
-	},
-	render: function (stats) {
-		var m, s, o;
-
-		m = new form.Map('smartdns', _('SmartDNS'));
-		m.title = _("SmartDNS Server");
-		m.description = _("SmartDNS is a local high-performance DNS server, supports finding fastest IP, "
-			+ "supports ad filtering, and supports avoiding DNS poisoning.");
-
-		s = m.section(form.NamedSection, '_status');
-		s.anonymous = true;
-		s.render = function (section_id) {
-			L.Poll.add(function () {
-				return L.resolveDefault(smartdnsServiceStatus()).then(function (res) {
-					var view = document.getElementById("service_status");
-					if (view == null) {
-						return;
-					}
-
-					view.innerHTML = smartdnsRenderStatus(res);
-				});
-			});
-
-			return E('div', { class: 'cbi-map' },
-				E('div', { class: 'cbi-section' }, [
-					E('div', { id: 'service_status' },
-						_('Collecting data ...'))
-				])
-			);
-		}
-
-		// Basic;
-		s = m.section(form.TypedSection, "smartdns", _("Settings"), _("General Settings"));
-		s.anonymous = true;
-
-		s.tab("settings", _("General Settings"));
-		s.tab("seconddns", _("Second Server Settings"));
-		s.tab("custom", _("Custom Settings"));
-
-		o = s.taboption("settings", form.Flag, "enabled", _("Enable"), _("Enable or disable smartdns server"));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// server name;
-		o = s.taboption("settings", form.Value, "server_name", _("Server Name"), _("Smartdns server name"));
-		o.default = "smartdns";
-		o.datatype = "hostname";
-		o.rempty = false;
-
-		// Port;
-		o = s.taboption("settings", form.Value, "port", _("Local Port"), _("Smartdns local server port"));
-		o.placeholder = 53;
-		o.default = 53;
-		o.datatype = "port";
-		o.rempty = false;
-
-		// Enable TCP server;
-		o = s.taboption("settings", form.Flag, "tcp_server", _("TCP Server"), _("Enable TCP DNS Server"));
-		o.rmempty = false;
-		o.default = o.enabled;
-
-		// Support IPV6;
-		o = s.taboption("settings", form.Flag, "ipv6_server", _("IPV6 Server"), _("Enable IPV6 DNS Server"));
-		o.rmempty = false;
-		o.default = o.enabled;
-
-		// Support DualStack ip selection;
-		o = s.taboption("settings", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"),
-			_("Enable IP selection between IPV4 and IPV6"));
-		o.rmempty = false;
-		o.default = o.enabled;
-
-		// Domain prefetch load ;
-		o = s.taboption("settings", form.Flag, "prefetch_domain", _("Domain prefetch"),
-			_("Enable domain prefetch, accelerate domain response speed."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// Domain Serve expired
-		o = s.taboption("settings", form.Flag, "serve_expired", _("Serve expired"),
-			_("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.default = o.enabled;
-
-		// Redirect;
-		o = s.taboption("settings", form.ListValue, "redirect", _("Redirect"), _("SmartDNS redirect mode"));
-		o.placeholder = "none";
-		o.value("none", _("none"));
-		o.value("dnsmasq-upstream", _("Run as dnsmasq upstream server"));
-		o.value("redirect", _("Redirect 53 port to SmartDNS"));
-		o.default = "none";
-		o.rempty = false;
-
-		// cache-size;
-		o = s.taboption("settings", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size"));
-		o.rempty = true;
-
-		// cache-size;
-		o = s.taboption("settings", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file"));
-		o.rmempty = false;
-		o.default = o.enabled;
-
-		// Force AAAA SOA
-		o = s.taboption("settings", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// Force HTTPS SOA
-		o = s.taboption("settings", form.Flag, "force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// rr-ttl;
-		o = s.taboption("settings", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result."));
-		o.rempty = true;
-
-		// rr-ttl-min;
-		o = s.taboption("settings", form.Value, "rr_ttl_min", _("Domain TTL Min"),
-			_("Minimum TTL for all domain result."));
-		o.rempty = true;
-		o.placeholder = "600";
-		o.default = 600;
-		o.optional = true;
-
-		// rr-ttl-max;
-		o = s.taboption("settings", form.Value, "rr_ttl_max", _("Domain TTL Max"),
-		_("Maximum TTL for all domain result."));
-		o.rempty = true;
-
-		// rr-ttl-reply-max;
-		o = s.taboption("settings", form.Value, "rr_ttl_reply_max", _("Domain Reply TTL Max"),
-		_("Maximum Reply TTL for all domain result."));
-		o.rempty = true;
-		
-		// second dns server;
-		// Eanble;
-		o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"),
-			_("Enable or disable second DNS server."));
-		o.default = o.disabled;
-		o.rempty = false;
-
-		// Port;
-		o = s.taboption("seconddns", form.Value, "seconddns_port", _("Local Port"), _("Smartdns local server port"));
-		o.placeholder = 6553;
-		o.default = 6553;
-		o.datatype = "port";
-		o.rempty = false;
-
-		// Enable TCP server;
-		o = s.taboption("seconddns", form.Flag, "seconddns_tcp_server", _("TCP Server"), _("Enable TCP DNS Server"));
-		o.rmempty = false;
-		o.default = o.enabled;
-
-		// dns server group;
-		o = s.taboption("seconddns", form.Value, "seconddns_server_group", _("Server Group"),
-			_("Query DNS through specific dns server group, such as office, home."));
-		o.rmempty = true;
-		o.placeholder = "default";
-		o.datatype = "hostname";
-		o.rempty = true;
-
-		o = s.taboption("seconddns", form.Flag, "seconddns_no_speed_check", _("Skip Speed Check"),
-			_("Do not check speed."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// skip address rules;
-		o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_addr", _("Skip Address Rules"),
-			_("Skip address rules."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// skip name server rules;
-		o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_nameserver", _("Skip Nameserver Rule"),
-			_("Skip nameserver rules."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// skip ipset rules;
-		o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_ipset", _("Skip Ipset Rule"),
-			_("Skip ipset rules."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// skip soa address rule;
-		o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_soa", _("Skip SOA Address Rule"),
-			_("Skip SOA address rules."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		o = s.taboption("seconddns", form.Flag, "seconddns_no_dualstack_selection", _("Skip Dualstack Selection"),
-			_("Skip Dualstack Selection."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// skip cache;
-		o = s.taboption("seconddns", form.Flag, "seconddns_no_cache", _("Skip Cache"), _("Skip Cache."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// Force AAAA SOA
-		o = s.taboption("seconddns", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
-		o.rmempty = false;
-		o.default = o.disabled;
-
-		// custom settings;
-		o = s.taboption("custom", form.TextValue, "custom_conf",
-			"", _("smartdns custom settings"));
-
-		o.rows = 20;
-		o.cfgvalue = function (section_id) {
-			return fs.trimmed('/etc/smartdns/custom.conf');
-		};
-		o.write = function (section_id, formvalue) {
-			return fs.write('/etc/smartdns/custom.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
-		};
-
-		o = s.taboption("custom", form.Flag, "coredump", _("Generate Coredump"),
-			_("Generate Coredump file when smartdns crash, coredump file is located at /tmp/smartdns.xxx.core."));
-		o.rmempty = false;
-		o.default = o.disabled;
-		// Upstream servers;
-		s = m.section(form.GridSection, "server", _("Upstream Servers"),
-			_("Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS servers, "
-				+ "including multiple foreign DNS servers."));
-		s.anonymous = true;
-		s.addremove = true;
-
-		s.tab('general', _('General Settings'));
-		s.tab('advanced', _('Advanced Settings'));
-
-		// enable flag;
-		o = s.taboption("general", form.Flag, "enabled", _("Enable"), _("Enable"));
-		o.rmempty = false;
-		o.default = o.enabled;
-		o.editable = true;
-
-		// name;
-		o = s.taboption("general", form.Value, "name", _("DNS Server Name"), _("DNS Server Name"));
-
-		// IP address;
-		o = s.taboption("general", form.Value, "ip", _("ip"), _("DNS Server ip"));
-		o.datatype = "or(ipaddr, string)";
-		o.rmempty = false;
-
-		// port;
-		o = s.taboption("general", form.Value, "port", _("port"), _("DNS Server port"));
-		o.placeholder = "default";
-		o.datatype = "port";
-		o.rempty = true;
-		o.depends("type", "udp");
-		o.depends("type", "tcp");
-		o.depends("type", "tls");
-
-		// type;
-		o = s.taboption("general", form.ListValue, "type", _("type"), _("DNS Server type"));
-		o.placeholder = "udp";
-		o.value("udp", _("udp"));
-		o.value("tcp", _("tcp"));
-		o.value("tls", _("tls"));
-		o.value("https", _("https"));
-		o.default = "udp";
-		o.rempty = false;
-
-		// Advanced Options
-		// server group
-		o = s.taboption("advanced", form.Value, "server_group", _("Server Group"), _("DNS Server group belongs to, "
-			+ "used with nameserver, such as office, home."))
-		o.rmempty = true
-		o.placeholder = "default"
-		o.datatype = "hostname"
-		o.rempty = true
-		o.modalonly = true;
-
-		// blacklist_ip
-		o = s.taboption("advanced", form.Flag, "blacklist_ip", _("IP Blacklist Filtering"),
-			_("Filtering IP with blacklist"))
-		o.rmempty = false
-		o.default = o.disabled
-		o.modalonly = true;
-
-		// TLS host verify
-		o = s.taboption("advanced", form.Value, "tls_host_verify", _("TLS Hostname Verify"),
-			_("Set TLS hostname to verify."))
-		o.default = ""
-		o.datatype = "string"
-		o.rempty = true
-		o.modalonly = true;
-		o.depends("type", "tls")
-		o.depends("type", "https")
-
-		// certificate verify
-		o = s.taboption("advanced", form.Flag, "no_check_certificate", _("No check certificate"),
-			_("Do not check certificate."))
-		o.rmempty = false
-		o.default = o.disabled
-		o.modalonly = true;
-		o.depends("type", "tls")
-		o.depends("type", "https")
-
-		// SNI host name
-		o = s.taboption("advanced", form.Value, "host_name", _("TLS SNI name"),
-			_("Sets the server name indication for query."))
-		o.default = ""
-		o.datatype = "hostname"
-		o.rempty = true
-		o.modalonly = true;
-		o.depends("type", "tls")
-		o.depends("type", "https")
-
-		// http host
-		o = s.taboption("advanced", form.Value, "http_host", _("HTTP Host"),
-			_("Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address."))
-		o.default = ""
-		o.datatype = "hostname"
-		o.rempty = true
-		o.modalonly = true;
-		o.depends("type", "https")
-
-		// SPKI pin
-		o = s.taboption("advanced", form.Value, "spki_pin", _("TLS SPKI Pinning"),
-			_("Used to verify the validity of the TLS server, The value is Base64 encoded SPKI fingerprint, "
-				+ "leaving blank to indicate that the validity of TLS is not verified."))
-		o.default = ""
-		o.datatype = "string"
-		o.rempty = true
-		o.modalonly = true;
-		o.depends("type", "tls")
-		o.depends("type", "https")
-
-		// other args
-		o = s.taboption("advanced", form.Value, "addition_arg", _("Additional Server Args"),
-			_("Additional Args for upstream dns servers"))
-		o.default = ""
-		o.rempty = true
-		o.modalonly = true;
-
-		// Doman addresss;
-		s = m.section(form.TypedSection, "smartdns", _("Advanced Settings"), _("Advanced Settings"));
-		s.anonymous = true;
-
-		s.tab("domain-address", _("Domain Address"), _("Set Specific domain ip address."));
-		s.tab("blackip-list", _("IP Blacklist"), _("Set Specific ip blacklist."));
-
-		o = s.taboption("domain-address", form.TextValue, "address_conf",
-			"",
-			_("Specify an IP address to return for any host in the given domains, Queries in the domains are never "
-				+ "forwarded and always replied to with the specified IP address which may be IPv4 or IPv6."));
-		o.rows = 20;
-		o.cfgvalue = function (section_id) {
-			return fs.trimmed('/etc/smartdns/address.conf');
-		};
-		o.write = function (section_id, formvalue) {
-			return fs.write('/etc/smartdns/address.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
-		};
-
-		// IP Blacklist;
-		// blacklist;
-		o = s.taboption("blackip-list", form.TextValue, "blackip_ip_conf",
-			"", _("Configure IP blacklists that will be filtered from the results of specific DNS server."));
-		o.rows = 20;
-		o.cfgvalue = function (section_id) {
-			return fs.trimmed('/etc/smartdns/blacklist-ip.conf');
-		};
-		o.write = function (section_id, formvalue) {
-			return fs.write('/etc/smartdns/blacklist-ip.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
-		};
-
-		// Doman addresss;
-		s = m.section(form.TypedSection, "smartdns", _("Technical Support"),
-			_("If you like this software, please buy me a cup of coffee."));
-		s.anonymous = true;
-
-		o = s.option(form.Button, "web");
-		o.title = _("SmartDNS official website");
-		o.inputtitle = _("open website");
-		o.inputstyle = "apply";
-		o.onclick = function () {
-			window.open("https://pymumu.github.io/smartdns", '_blank');
-		};
-
-		o = s.option(form.Button, "Donate");
-		o.title = _("Donate to smartdns");
-		o.inputtitle = _("Donate");
-		o.inputstyle = "apply";
-		o.onclick = function () {
-			window.open("https://pymumu.github.io/smartdns/#donate", '_blank');
-		};
-
-		return m.render();
-	}
-});
+ 'use strict';
+ 'require fs';
+ 'require uci';
+ 'require form';
+ 'require view';
+ 'require poll';
+ 'require rpc';
+ 
+ var conf = 'smartdns';
+ var callServiceList = rpc.declare({
+	 object: 'service',
+	 method: 'list',
+	 params: ['name'],
+	 expect: { '': {} }
+ });
+ 
+ function getServiceStatus() {
+	 return L.resolveDefault(callServiceList(conf), {})
+		 .then(function (res) {
+			 var isrunning = false;
+			 try {
+				 isrunning = res[conf]['instances']['smartdns']['running'];
+			 } catch (e) { }
+			 return isrunning;
+		 });
+ }
+ 
+ function smartdnsServiceStatus() {
+	 return Promise.all([
+		 getServiceStatus()
+	 ]);
+ }
+ 
+ function smartdnsRenderStatus(res) {
+	 var renderHTML = "";
+	 var isRunning = res[0];
+ 
+	 if (isRunning) {
+		 renderHTML += "<span style=\"color:green;font-weight:bold\">SmartDNS - " + _("RUNNING") + "</span>";
+	 } else {
+		 renderHTML += "<span style=\"color:red;font-weight:bold\">SmartDNS - " + _("NOT RUNNING") + "</span>";
+		 return renderHTML;
+	 }
+ 
+	 return renderHTML;
+ }
+ 
+ return view.extend({
+	 load: function () {
+		 return Promise.all([
+			 uci.load('smartdns'),
+			 uci.load('dhcp')
+		 ]);
+	 },
+	 render: function (stats) {
+		 var m, s, o;
+ 
+		 m = new form.Map('smartdns', _('SmartDNS'));
+		 m.title = _("SmartDNS Server");
+		 m.description = _("SmartDNS is a local high-performance DNS server, supports finding fastest IP, "
+			 + "supports ad filtering, and supports avoiding DNS poisoning.");
+ 
+		 s = m.section(form.NamedSection, '_status');
+		 s.anonymous = true;
+		 s.render = function (section_id) {
+			 var renderStatus = function () {
+				 return L.resolveDefault(smartdnsServiceStatus()).then(function (res) {
+					 var view = document.getElementById("service_status");
+					 if (view == null) {
+						 return;
+					 }
+ 
+					 view.innerHTML = smartdnsRenderStatus(res);
+				 });
+			 }
+			 poll.add(renderStatus);
+			 setTimeout(renderStatus, 1000);
+ 
+			 return E('div', { class: 'cbi-map' },
+				 E('div', { class: 'cbi-section' }, [
+					 E('div', { id: 'service_status' },
+						 _('Collecting data ...'))
+				 ])
+			 );
+		 }
+ 
+		 // Basic;
+		 s = m.section(form.TypedSection, "smartdns", _("Settings"), _("General Settings"));
+		 s.anonymous = true;
+ 
+		 s.tab("settings", _("General Settings"));
+		 s.tab("seconddns", _("Second Server Settings"));
+		 s.tab("custom", _("Custom Settings"));
+ 
+		 o = s.taboption("settings", form.Flag, "enabled", _("Enable"), _("Enable or disable smartdns server"));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // server name;
+		 o = s.taboption("settings", form.Value, "server_name", _("Server Name"), _("Smartdns server name"));
+		 o.default = "smartdns";
+		 o.datatype = "hostname";
+		 o.rempty = false;
+ 
+		 // Port;
+		 o = s.taboption("settings", form.Value, "port", _("Local Port"), _("Smartdns local server port"));
+		 o.placeholder = 53;
+		 o.default = 53;
+		 o.datatype = "port";
+		 o.rempty = false;
+ 
+		 // Enable TCP server;
+		 o = s.taboption("settings", form.Flag, "tcp_server", _("TCP Server"), _("Enable TCP DNS Server"));
+		 o.rmempty = false;
+		 o.default = o.enabled;
+ 
+		 // Support IPV6;
+		 o = s.taboption("settings", form.Flag, "ipv6_server", _("IPV6 Server"), _("Enable IPV6 DNS Server"));
+		 o.rmempty = false;
+		 o.default = o.enabled;
+ 
+		 // Support DualStack ip selection;
+		 o = s.taboption("settings", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"),
+			 _("Enable IP selection between IPV4 and IPV6"));
+		 o.rmempty = false;
+		 o.default = o.enabled;
+ 
+		 // Domain prefetch load ;
+		 o = s.taboption("settings", form.Flag, "prefetch_domain", _("Domain prefetch"),
+			 _("Enable domain prefetch, accelerate domain response speed."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // Domain Serve expired
+		 o = s.taboption("settings", form.Flag, "serve_expired", _("Serve expired"),
+			 _("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.default = o.enabled;
+ 
+		 // cache-size;
+		 o = s.taboption("settings", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size"));
+		 o.rempty = true;
+ 
+		 // cache-size;
+		 o = s.taboption("settings", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file."));
+		 o.rmempty = false;
+		 o.default = o.enabled;
+
+		 // auto-conf-dnsmasq;
+		 o = s.taboption("settings", form.Flag, "auto_set_dnsmasq", _("Automatically Set Dnsmasq"), _("Automatically set as upstream of dnsmasq when port changes."));
+		 o.rmempty = false;
+		 o.default = o.enabled;
+ 
+		 // Force AAAA SOA
+		 o = s.taboption("settings", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // Force HTTPS SOA
+		 o = s.taboption("settings", form.Flag, "force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // rr-ttl;
+		 o = s.taboption("settings", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result."));
+		 o.rempty = true;
+ 
+		 // rr-ttl-min;
+		 o = s.taboption("settings", form.Value, "rr_ttl_min", _("Domain TTL Min"),
+			 _("Minimum TTL for all domain result."));
+		 o.rempty = true;
+		 o.placeholder = "600";
+		 o.default = 600;
+		 o.optional = true;
+ 
+		 // rr-ttl-max;
+		 o = s.taboption("settings", form.Value, "rr_ttl_max", _("Domain TTL Max"),
+		 _("Maximum TTL for all domain result."));
+		 o.rempty = true;
+ 
+		 // rr-ttl-reply-max;
+		 o = s.taboption("settings", form.Value, "rr_ttl_reply_max", _("Reply Domain TTL Max"),
+		 _("Reply maximum TTL for all domain result."));
+		 o.rempty = true;
+		 
+		 // second dns server;
+		 // Eanble;
+		 o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"),
+			 _("Enable or disable second DNS server."));
+		 o.default = o.disabled;
+		 o.rempty = false;
+ 
+		 // Port;
+		 o = s.taboption("seconddns", form.Value, "seconddns_port", _("Local Port"), _("Smartdns local server port"));
+		 o.placeholder = 6553;
+		 o.default = 6553;
+		 o.datatype = "port";
+		 o.rempty = false;
+ 
+		 // Enable TCP server;
+		 o = s.taboption("seconddns", form.Flag, "seconddns_tcp_server", _("TCP Server"), _("Enable TCP DNS Server"));
+		 o.rmempty = false;
+		 o.default = o.enabled;
+ 
+		 // dns server group;
+		 o = s.taboption("seconddns", form.Value, "seconddns_server_group", _("Server Group"),
+			 _("Query DNS through specific dns server group, such as office, home."));
+		 o.rmempty = true;
+		 o.placeholder = "default";
+		 o.datatype = "hostname";
+		 o.rempty = true;
+ 
+		 o = s.taboption("seconddns", form.Flag, "seconddns_no_speed_check", _("Skip Speed Check"),
+			 _("Do not check speed."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // skip address rules;
+		 o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_addr", _("Skip Address Rules"),
+			 _("Skip address rules."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // skip name server rules;
+		 o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_nameserver", _("Skip Nameserver Rule"),
+			 _("Skip nameserver rules."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // skip ipset rules;
+		 o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_ipset", _("Skip Ipset Rule"),
+			 _("Skip ipset rules."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // skip soa address rule;
+		 o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_soa", _("Skip SOA Address Rule"),
+			 _("Skip SOA address rules."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 o = s.taboption("seconddns", form.Flag, "seconddns_no_dualstack_selection", _("Skip Dualstack Selection"),
+			 _("Skip Dualstack Selection."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // skip cache;
+		 o = s.taboption("seconddns", form.Flag, "seconddns_no_cache", _("Skip Cache"), _("Skip Cache."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // Force AAAA SOA
+		 o = s.taboption("seconddns", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+ 
+		 // custom settings;
+		 o = s.taboption("custom", form.TextValue, "custom_conf",
+			 "", _("smartdns custom settings"));
+ 
+		 o.rows = 20;
+		 o.cfgvalue = function (section_id) {
+			 return fs.trimmed('/etc/smartdns/custom.conf');
+		 };
+		 o.write = function (section_id, formvalue) {
+			 return fs.write('/etc/smartdns/custom.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
+		 };
+ 
+		 o = s.taboption("custom", form.Flag, "coredump", _("Generate Coredump"),
+			 _("Generate Coredump file when smartdns crash, coredump file is located at /tmp/smartdns.xxx.core."));
+		 o.rmempty = false;
+		 o.default = o.disabled;
+		 // Upstream servers;
+		 s = m.section(form.GridSection, "server", _("Upstream Servers"),
+			 _("Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS servers, "
+				 + "including multiple foreign DNS servers."));
+		 s.anonymous = true;
+		 s.addremove = true;
+ 
+		 s.tab('general', _('General Settings'));
+		 s.tab('advanced', _('Advanced Settings'));
+ 
+		 // enable flag;
+		 o = s.taboption("general", form.Flag, "enabled", _("Enable"), _("Enable"));
+		 o.rmempty = false;
+		 o.default = o.enabled;
+		 o.editable = true;
+ 
+		 // name;
+		 o = s.taboption("general", form.Value, "name", _("DNS Server Name"), _("DNS Server Name"));
+ 
+		 // IP address;
+		 o = s.taboption("general", form.Value, "ip", _("ip"), _("DNS Server ip"));
+		 o.datatype = "or(ipaddr, string)";
+		 o.rmempty = false;
+ 
+		 // port;
+		 o = s.taboption("general", form.Value, "port", _("port"), _("DNS Server port"));
+		 o.placeholder = "default";
+		 o.datatype = "port";
+		 o.rempty = true;
+		 o.depends("type", "udp");
+		 o.depends("type", "tcp");
+		 o.depends("type", "tls");
+ 
+		 // type;
+		 o = s.taboption("general", form.ListValue, "type", _("type"), _("DNS Server type"));
+		 o.placeholder = "udp";
+		 o.value("udp", _("udp"));
+		 o.value("tcp", _("tcp"));
+		 o.value("tls", _("tls"));
+		 o.value("https", _("https"));
+		 o.default = "udp";
+		 o.rempty = false;
+ 
+		 // Advanced Options
+		 // server group
+		 o = s.taboption("advanced", form.Value, "server_group", _("Server Group"), _("DNS Server group belongs to, "
+			 + "used with nameserver, such as office, home."))
+		 o.rmempty = true
+		 o.placeholder = "default"
+		 o.datatype = "hostname"
+		 o.rempty = true
+		 o.modalonly = true;
+ 
+		 // blacklist_ip
+		 o = s.taboption("advanced", form.Flag, "blacklist_ip", _("IP Blacklist Filtering"),
+			 _("Filtering IP with blacklist"))
+		 o.rmempty = false
+		 o.default = o.disabled
+		 o.modalonly = true;
+ 
+		 // TLS host verify
+		 o = s.taboption("advanced", form.Value, "tls_host_verify", _("TLS Hostname Verify"),
+			 _("Set TLS hostname to verify."))
+		 o.default = ""
+		 o.datatype = "string"
+		 o.rempty = true
+		 o.modalonly = true;
+		 o.depends("type", "tls")
+		 o.depends("type", "https")
+ 
+		 // certificate verify
+		 o = s.taboption("advanced", form.Flag, "no_check_certificate", _("No check certificate"),
+			 _("Do not check certificate."))
+		 o.rmempty = false
+		 o.default = o.disabled
+		 o.modalonly = true;
+		 o.depends("type", "tls")
+		 o.depends("type", "https")
+ 
+		 // SNI host name
+		 o = s.taboption("advanced", form.Value, "host_name", _("TLS SNI name"),
+			 _("Sets the server name indication for query."))
+		 o.default = ""
+		 o.datatype = "hostname"
+		 o.rempty = true
+		 o.modalonly = true;
+		 o.depends("type", "tls")
+		 o.depends("type", "https")
+ 
+		 // http host
+		 o = s.taboption("advanced", form.Value, "http_host", _("HTTP Host"),
+			 _("Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address."))
+		 o.default = ""
+		 o.datatype = "hostname"
+		 o.rempty = true
+		 o.modalonly = true;
+		 o.depends("type", "https")
+ 
+		 // SPKI pin
+		 o = s.taboption("advanced", form.Value, "spki_pin", _("TLS SPKI Pinning"),
+			 _("Used to verify the validity of the TLS server, The value is Base64 encoded SPKI fingerprint, "
+				 + "leaving blank to indicate that the validity of TLS is not verified."))
+		 o.default = ""
+		 o.datatype = "string"
+		 o.rempty = true
+		 o.modalonly = true;
+		 o.depends("type", "tls")
+		 o.depends("type", "https")
+ 
+		 // other args
+		 o = s.taboption("advanced", form.Value, "addition_arg", _("Additional Server Args"),
+			 _("Additional Args for upstream dns servers"))
+		 o.default = ""
+		 o.rempty = true
+		 o.modalonly = true;
+ 
+		 // Doman addresss;
+		 s = m.section(form.TypedSection, "smartdns", _("Advanced Settings"), _("Advanced Settings"));
+		 s.anonymous = true;
+ 
+		 s.tab("domain-address", _("Domain Address"), _("Set Specific domain ip address."));
+		 s.tab("blackip-list", _("IP Blacklist"), _("Set Specific ip blacklist."));
+ 
+		 o = s.taboption("domain-address", form.TextValue, "address_conf",
+			 "",
+			 _("Specify an IP address to return for any host in the given domains, Queries in the domains are never "
+				 + "forwarded and always replied to with the specified IP address which may be IPv4 or IPv6."));
+		 o.rows = 20;
+		 o.cfgvalue = function (section_id) {
+			 return fs.trimmed('/etc/smartdns/address.conf');
+		 };
+		 o.write = function (section_id, formvalue) {
+			 return fs.write('/etc/smartdns/address.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
+		 };
+ 
+		 // IP Blacklist;
+		 // blacklist;
+		 o = s.taboption("blackip-list", form.TextValue, "blackip_ip_conf",
+			 "", _("Configure IP blacklists that will be filtered from the results of specific DNS server."));
+		 o.rows = 20;
+		 o.cfgvalue = function (section_id) {
+			 return fs.trimmed('/etc/smartdns/blacklist-ip.conf');
+		 };
+		 o.write = function (section_id, formvalue) {
+			 return fs.write('/etc/smartdns/blacklist-ip.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n');
+		 };
+ 
+		 // Doman addresss;
+		 s = m.section(form.TypedSection, "smartdns", _("Technical Support"),
+			 _("If you like this software, please buy me a cup of coffee."));
+		 s.anonymous = true;
+ 
+		 o = s.option(form.Button, "web");
+		 o.title = _("SmartDNS official website");
+		 o.inputtitle = _("open website");
+		 o.inputstyle = "apply";
+		 o.onclick = function () {
+			 window.open("https://pymumu.github.io/smartdns", '_blank');
+		 };
+ 
+		 o = s.option(form.Button, "Donate");
+		 o.title = _("Donate to smartdns");
+		 o.inputtitle = _("Donate");
+		 o.inputstyle = "apply";
+		 o.onclick = function () {
+			 window.open("https://pymumu.github.io/smartdns/#donate", '_blank');
+		 };
+ 
+		 return m.render();
+	 }
+ });
+ 

+ 97 - 63
package/openwrt/files/etc/init.d/smartdns

@@ -31,6 +31,7 @@ CUSTOM_CONF="$SMARTDNS_CONF_DIR/custom.conf"
 SMARTDNS_CONF_TMP="${SMARTDNS_CONF}.tmp"
 COREDUMP="0"
 RESPAWN="1"
+UPSTREAM_SERVER_NUM=0
 
 set_forward_dnsmasq()
 {
@@ -40,13 +41,12 @@ set_forward_dnsmasq()
 	if echo "$OLD_SERVER" | grep "^$addr" >/dev/null 2>&1; then
 		return
 	fi
+
 	uci delete dhcp.@dnsmasq[0].server 2>/dev/null
 	uci add_list dhcp.@dnsmasq[0].server="$addr"
-	for server in $OLD_SERVER; do
-		[ "$server" = "$addr" ] && continue
-		uci add_list dhcp.@dnsmasq[0].server="$server"
-	done
 	uci set dhcp.@dnsmasq[0].noresolv=1
+	uci set dhcp.@dnsmasq[0].rebind_protection=0
+	uci set dhcp.@dnsmasq[0].domainneeded=0
 	uci commit dhcp
 	/etc/init.d/dnsmasq restart
 }
@@ -59,16 +59,33 @@ stop_forward_dnsmasq()
 	if ! echo "$OLD_SERVER" | grep "^$addr" >/dev/null 2>&1; then
 		return
 	fi
-
-	uci del_list dhcp.@dnsmasq[0].server="$addr" 2>/dev/null
-	addrlist="$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)"
-	[ -z "$addrlist" ] && {
-		uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null
-	}
+	
+	uci delete dhcp.@dnsmasq[0].server  2>/dev/null
+	uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null
+	uci set dhcp.@dnsmasq[0].rebind_protection=1
+	uci set dhcp.@dnsmasq[0].domainneeded=1
 	uci commit dhcp
 	/etc/init.d/dnsmasq restart
 }
 
+auto_set_dnsmasq()
+{
+	local port="$1"
+	local old_port="$2"
+
+	[ "$port" = "53" ] || set_forward_dnsmasq $port
+	[ "$port" = "$old_port" ] || stop_forward_dnsmasq $old_port
+}
+
+stop_set_dnsmasq()
+{
+	local port="$1"
+	local old_port="$2"
+	stop_forward_dnsmasq "$port"
+	[ "$port" == "$old_port" ] || stop_forward_dnsmasq "$old_port"
+}
+
+
 set_main_dns()
 {
 	uci set dhcp.@dnsmasq[0].port=0
@@ -78,38 +95,11 @@ set_main_dns()
 
 stop_main_dns()
 {
-	uci delete dhcp.@dnsmasq[0].port
+	uci delete dhcp.@dnsmasq[0].port 2>/dev/null
 	uci commit dhcp
 	/etc/init.d/dnsmasq restart
 }
 
-set_iptable()
-{
-	local ipv6_server=$1
-	local tcp_server=$2
-
-	IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}')"
-	for IP in $IPS
-	do
-		if [ "$tcp_server" = "1" ]; then
-			iptables -t nat -A PREROUTING -p tcp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" >/dev/null 2>&1
-		fi
-		iptables -t nat -A PREROUTING -p udp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" >/dev/null 2>&1
-	done
-
-	[ "$ipv6_server" = 0 ] && return
-
-	IPS="$(ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}')"
-	for IP in $IPS
-	do
-		if [ "$tcp_server" = "1" ]; then
-			ip6tables -t nat -A PREROUTING -p tcp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" >/dev/null 2>&1
-		fi
-		ip6tables -t nat -A PREROUTING -p udp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" >/dev/null 2>&1
-	done
-
-}
-
 clear_iptable()
 {
 	local OLD_PORT="$1"
@@ -218,6 +208,21 @@ load_server()
 	[ "$type" = "https" ] && DNS_ADDRESS="$ip"
 
 	conf_append "$SERVER" "$DNS_ADDRESS $ADDITIONAL_ARGS $addition_arg"
+	((UPSTREAM_SERVER_NUM=UPSTREAM_SERVER_NUM+1))
+}
+
+load_resolv_conf()
+{
+	resolve_file="$(uci get dhcp.@dnsmasq[0].resolvfile 2>/dev/null)"
+	[ -z "$dhcp.@dnsmasq[0].resolvfile" ] && return 1
+	[ -e "$resolve_file" ] || return 1
+
+	while read line
+	do
+		IP="$(echo "$line" | grep "nameserver " | awk '{print $2}')"
+		[ -z "$IP" ] && continue
+		conf_append "server" "$IP"
+	done < $resolve_file
 }
 
 load_second_server()
@@ -274,7 +279,8 @@ load_service()
 {
 	local section="$1"
 	args=""
-	dnsmase_lease_file="$(uci get dhcp.@dnsmasq[0].leasefile 2>/dev/null)"
+	dnsmasq_lease_file="$(uci get dhcp.@dnsmasq[0].leasefile 2>/dev/null)"
+	dnsmasq_port="$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)"
 	qtype_soa_list=""
 
 	mkdir -p $SMARTDNS_VAR_CONF_DIR
@@ -301,13 +307,11 @@ load_service()
 	config_get serve_expired "$section" "serve_expired" "0"
 	[ "$serve_expired" = "1" ] && conf_append "serve-expired" "yes"
 
-	SMARTDNS_PORT="$port"
-
 	config_get cache_size "$section" "cache_size" ""
 	[ -z "$cache_size" ] || conf_append "cache-size" "$cache_size"
 
 	config_get resolve_local_hostnames "$section" "resolve_local_hostnames" "1"
-	[ -z "$resolve_local_hostnames" ] || conf_append "dnsmasq-lease-file" "$dnsmase_lease_file"
+	[ "$resolve_local_hostnames" = "1" ] && conf_append "dnsmasq-lease-file" "$dnsmasq_lease_file"
 
 	config_get force_aaaa_soa "$section" "force_aaaa_soa" "0"
 	[ "$force_aaaa_soa" = "1" ] && qtype_soa_list="$qtype_soa_list 28"
@@ -315,6 +319,8 @@ load_service()
 	config_get force_https_soa "$section" "force_https_soa" "0"
 	[ "$force_https_soa" = "1" ] && qtype_soa_list="$qtype_soa_list 65"
 
+	config_get auto_set_dnsmasq "$section" "auto_set_dnsmasq" ""
+
 	config_get rr_ttl "$section" "rr_ttl" ""
 	[ -z "$rr_ttl" ] || conf_append "rr-ttl" "$rr_ttl"
 
@@ -339,42 +345,49 @@ load_service()
 	config_get log_file "$section" "log_file" ""
 	[ -z "$log_file" ] || conf_append "log-file" "$log_file"
 
-	config_get redirect "$section" "redirect" "none"
-	config_get old_redirect "$section" "old_redirect" "none"
+	config_get redirect "$section" "redirect" ""
 	config_get old_port "$section" "old_port" "0"
-	config_get old_enabled "$section" "old_enabled" "0"
 
 	[ -z "$qtype_soa_list" ] || conf_append "force-qtype-SOA" "$qtype_soa_list"
 
-	if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$SMARTDNS_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then
-		[ "$old_redirect" = "none" ] || {
-			[ "$old_port" = "0" ] || clear_iptable "$old_port" "$ipv6_server"
-			[ "$old_redirect" = "dnsmasq-upstream" ] && stop_forward_dnsmasq "$old_port"
+	# upgrade old configuration
+	if [ "$redirect" = "redirect" ] || [ "$redirect" = "dnsmasq-upstream" ] || [ "$redirect" = "none" ]; then
+		clear_iptable "$port"
+		clear_iptable "$old_port"
+		stop_forward_dnsmasq "$port"
+		stop_forward_dnsmasq "$old_port"
+		[ "$redirect" = "none" ] || {
+			uci delete smartdns.@smartdns[0].port="53" 2>/dev/null
+			port="53"
 		}
+		uci delete smartdns.@smartdns[0].redirect 2>/dev/null
+		uci delete smartdns.@smartdns[0].old_redirect 2>/dev/null
+		uci delete smartdns.@smartdns[0].old_enabled 2>/dev/null
 	fi
 
-	[ "$enabled" = "0" ] && [ "$SMARTDNS_PORT" = "53" ] && stop_main_dns 
-	[ "$old_port" != "$SMARTDNS_PORT" ] && [ "$old_port" = "53" ] && stop_main_dns 
+	SMARTDNS_PORT="$port"
+	[ -z "${dnsmasq_port}" ] && dnsmasq_port="53"
+	[ "$old_port" == "53" ] && [ "$dnsmasq_port" = "0" ] && {
+		[ "$SMARTDNS_PORT" = "53" ] || stop_main_dns
+		[ "$enabled" = "0" ] && stop_main_dns
+	}
+
+	[ "$enabled" = "0" ] && [ "$auto_set_dnsmasq" = "1" ] && {
+		[ "$SMARTDNS_PORT" = "53" ] || stop_set_dnsmasq "$SMARTDNS_PORT" "$old_port"
+	}
 
-	uci delete smartdns.@smartdns[0].old_redirect 2>/dev/null
 	uci delete smartdns.@smartdns[0].old_port 2>/dev/null
-	uci delete smartdns.@smartdns[0].old_enabled 2>/dev/null
-	uci add_list smartdns.@smartdns[0].old_redirect="$redirect" 2>/dev/null
-	uci add_list smartdns.@smartdns[0].old_port="$SMARTDNS_PORT" 2>/dev/null
-	uci add_list smartdns.@smartdns[0].old_enabled="$enabled" 2>/dev/null
+	uci set smartdns.@smartdns[0].old_port="$SMARTDNS_PORT" 2>/dev/null
 	uci commit smartdns
 
 	[ "$enabled" -gt 0 ] || return 1
 
-	if [ "$redirect" = "redirect" ]; then
-		set_iptable $ipv6_server $tcp_server
-	elif [ "$redirect" = "dnsmasq-upstream" ]; then
-		set_forward_dnsmasq "$SMARTDNS_PORT"
+	[ "$auto_set_dnsmasq" = "1" ] && auto_set_dnsmasq "$SMARTDNS_PORT" "$old_port"
+	if [ "$auto_set_dnsmasq" = "0" ] || [ "$SMARTDNS_PORT" = "53" ] ; then
+		stop_set_dnsmasq "$SMARTDNS_PORT" "$old_port"
 	fi
 
-	if [ "$SMARTDNS_PORT" = "53" ]; then
-		set_main_dns
-	fi
+	[ "$dnsmasq_port" = "$SMARTDNS_PORT" ] && set_main_dns
 
 	if [ "$ipv6_server" = "1" ]; then
 		conf_append "bind" "[::]:$SMARTDNS_PORT"
@@ -394,6 +407,8 @@ load_service()
 
 	config_foreach load_server "server"
 
+	[ "$UPSTREAM_SERVER_NUM" -gt "0" ] || load_resolv_conf
+
 	{
 		echo "conf-file $ADDRESS_CONF"
 		echo "conf-file $BLACKLIST_IP_CONF"
@@ -417,6 +432,19 @@ load_service()
 	procd_close_instance
 }
 
+unload_service()
+{
+	local section="$1"
+	dnsmasq_port="$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)"
+	config_get port "$section" "port" "53"
+	config_get old_port "$section" "old_port" "0"
+	[ -z "${dnsmasq_port}" ] && dnsmasq_port="53"
+	[ "$old_port" = "53" ] && [ "$dnsmasq_port" = "0" ] && stop_main_dns
+	[ "$auto_set_dnsmasq" = "1" ] && {
+		[ "$port" = "53" ] || stop_set_dnsmasq "$port" "$old_port"
+	}
+}
+
 start_service()
 {
 	config_load "smartdns"
@@ -428,3 +456,9 @@ reload_service()
 	stop
 	start
 }
+
+stop_service()
+{
+	config_load "smartdns"
+	config_foreach unload_service "smartdns"
+}