Compare commits

...

23 Commits

Author SHA1 Message Date
Nick Peng
fa0ab28bab openwrt: restore dns redirect after disable smartdns 2022-09-25 11:08:26 +08:00
Nick Peng
9bca51beaf openwrt: fix dnsmasq redirect issue 2022-09-24 23:51:06 +08:00
Nick Peng
1640e9e6a1 smartdns: fix kernel dmesg warnings 2022-09-24 20:14:00 +08:00
Nick Peng
33ead3afbd luci: fix redirect error message issue 2022-09-15 23:17:58 +08:00
Nick Peng
1991a0b102 luci: add hint when set dnsmasq failure. 2022-09-14 23:45:39 +08:00
Nick Peng
1f1fd118de Feature: add domain-set option, simplify domain name rule settings 2022-09-08 00:41:17 +08:00
zxlhhyccc
8532205844 luci: fix rr-ttl-reply-max translate 2022-09-02 22:28:14 +08:00
Nick Peng
822f02bab9 luci: auto disable dns redirect for some firmware 2022-09-01 20:00:31 +08:00
Nick Peng
d8c53a6215 luci: fix second dns force AAAA soa options not working issue. 2022-09-01 00:32:52 +08:00
Nick Peng
e13a8c0ec5 luci: disable auto set dnsmasq when update from redirect mode none 2022-09-01 00:22:13 +08:00
Nick Peng
7c4ce074a5 luci: fix auto setting issue 2022-08-31 22:05:26 +08:00
Nick Peng
e6d533e2c5 luci: remove redirect feature and set as main dns server automatically when port is 53 2022-08-31 00:58:31 +08:00
Nick Peng
7b3dcd31f9 openwrt: support set smartdns as main server when port is 53 2022-08-30 01:46:11 +08:00
Nick Peng
0eef67c119 luci: fix warning when save config 2022-08-30 00:18:11 +08:00
Nick Peng
455924befe dns_client: fix default edns not working issue 2022-08-29 18:48:45 +08:00
Nick Peng
b75f7e14fe conf: fix typo 2022-08-29 18:19:38 +08:00
Nick Peng
64e5b326cc luci: fix status section not working issue and add some options 2022-08-28 17:30:24 +08:00
Nick Peng
f659cf3725 dns_conf: support relative path for dnsmasq-lease-file 2022-08-28 10:22:14 +08:00
Nick Peng
83c8105312 dns_server: fix only cache on ip address result issue 2022-08-24 20:05:35 +08:00
Nick Peng
fecc313e03 dns_server: fix SERVERFAIL when A is 127.0.0.1 2022-08-23 22:49:41 +08:00
Nick Peng
145f7cfa42 dns_server: make the TTL of the first request to 2s & fix hostname issue. 2022-08-21 18:29:44 +08:00
Nick Peng
464f2adaa7 fast_ping: fix race condition 2022-08-21 18:29:44 +08:00
Zhong Lufan
7c9288f887 Readme: Fix typo 2022-08-19 19:36:46 +08:00
21 changed files with 1545 additions and 923 deletions

104
ReadMe.md
View File

@@ -259,14 +259,9 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
3. 启用服务 3. 启用服务
SmartDNS 服务生效方法有两种,一种是**直接作为主 DNS 服务**,另一种是**作为 DNSmasq 的上游** * 替换默认Dndmasq为主DNS。
默认情况下SmartDNS 采用第一种方式。如下两种方式根据需求选择即可。
- **方法一:作为主 DNS 服务(默认方案)** 登录 OpenWrt 管理界面,点击 `Services` -> `SmartDNS` -> `port`,设置端口号为`53`smartdns会自动接管主DNS服务器。
* 启用 SmartDNS 的 53 端口重定向
登录 OpenWrt 管理界面,点击 `Services` -> `SmartDNS` -> `redirect`,选择 `重定向 53 端口到 SmartDNS `启用 53 端口转发。
* 检测转发服务是否配置成功 * 检测转发服务是否配置成功
@@ -287,64 +282,6 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
smartdns name = smartdns. 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地址。
4. 启动服务 4. 启动服务
勾选配置页面中的 `Enable启用`来启动 SmartDNS。 勾选配置页面中的 `Enable启用`来启动 SmartDNS。
@@ -352,7 +289,14 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
5. **注意:** 5. **注意:**
* 如已经安装 ChinaDNS建议将 ChinaDNS 的上游配置为 SmartDNS。 * 如已经安装 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
```
### 华硕路由器原生固件 / 梅林固件 ### 华硕路由器原生固件 / 梅林固件
@@ -579,12 +523,13 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
| server-tls | 上游 TLS DNS | 无 | 可重复。<br>[ip][:port]:服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]TLS 合法性校验 SPKI 值base64 编码的 sha256 SPKI pin 值<br>[-host-name]TLS SNI 名称<br>[-tls-host-verify]TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围<br>[-group [group] ...]DNS 服务器所属组,比如 office 和 foreign和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-tls 8.8.8.8:853 | | server-tls | 上游 TLS DNS | 无 | 可重复。<br>[ip][:port]:服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]TLS 合法性校验 SPKI 值base64 编码的 sha256 SPKI pin 值<br>[-host-name]TLS SNI 名称<br>[-tls-host-verify]TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围<br>[-group [group] ...]DNS 服务器所属组,比如 office 和 foreign和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-tls 8.8.8.8:853 |
| server-https | 上游 HTTPS DNS | 无 | 可重复。<br>https://[host][:port]/path服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]TLS 合法性校验 SPKI 值base64 编码的 sha256 SPKI pin 值<br>[-host-name]TLS SNI 名称<br>[-http-host]http 协议头主机名<br>[-tls-host-verify]TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围。<br>[-group [group] ...]DNS 服务器所属组,比如 office 和 foreign和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-https https://cloudflare-dns.com/dns-query | | server-https | 上游 HTTPS DNS | 无 | 可重复。<br>https://[host][:port]/path服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]TLS 合法性校验 SPKI 值base64 编码的 sha256 SPKI pin 值<br>[-host-name]TLS SNI 名称<br>[-http-host]http 协议头主机名<br>[-tls-host-verify]TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围。<br>[-group [group] ...]DNS 服务器所属组,比如 office 和 foreign和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-https https://cloudflare-dns.com/dns-query |
| speed-check-mode | 测速模式选择 | 无 | [ping\|tcp:[80]\|none] | speed-check-mode ping,tcp:80,tcp:443 | | speed-check-mode | 测速模式选择 | 无 | [ping\|tcp:[80]\|none] | speed-check-mode ping,tcp:80,tcp:443 |
| response-mode | 首次查询响应模式 | first-ping |模式:[fisrt-ping\|fastest-ip\|first-response]<br> [first-ping]: 最快ping响应地址模式DNS上游最快查询时延+ping时延最短查询等待与链接体验最佳;<br>[fastest-ip]: 最快IP地址模式查询到的所有IP地址中ping最短的IP。需等待IP测速; <br>[first-response]: 最快响应的DNS结果DNS查询等待时间最短返回的IP地址可能不是最快。| response-mode first-ping | | response-mode | 首次查询响应模式 | first-ping |模式:[fisrt-ping\|fastest-ip\|fastest-response]<br> [first-ping]: 最快ping响应地址模式DNS上游最快查询时延+ping时延最短查询等待与链接体验最佳;<br>[fastest-ip]: 最快IP地址模式查询到的所有IP地址中ping最短的IP。需等待IP测速; <br>[fastest-response]: 最快响应的DNS结果DNS查询等待时间最短返回的IP地址可能不是最快。| response-mode first-ping |
| address | 指定域名 IP 地址 | 无 | address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6] <br>- 表示忽略 <br># 表示返回 SOA <br>4 表示 IPv4 <br>6 表示 IPv6 | address /www.example.com/1.2.3.4 | | address | 指定域名 IP 地址 | 无 | address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6] <br>- 表示忽略 <br># 表示返回 SOA <br>4 表示 IPv4 <br>6 表示 IPv6 | address /www.example.com/1.2.3.4 |
| nameserver | 指定域名使用 server 组解析 | 无 | nameserver /domain/[group\|-], group 为组名,- 表示忽略此规则,配套 server 中的 -group 参数使用 | nameserver /www.example.com/office | | nameserver | 指定域名使用 server 组解析 | 无 | nameserver /domain/[group\|-], group 为组名,- 表示忽略此规则,配套 server 中的 -group 参数使用 | nameserver /www.example.com/office |
| ipset | 域名 ipset | 无 | ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]]-表示忽略 | ipset /www.example.com/#4:dns4,#6:- | | ipset | 域名 ipset | 无 | ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]]-表示忽略 | ipset /www.example.com/#4:dns4,#6:- |
| ipset-timeout | 设置 ipset 超时功能启用 | 自动 | [yes] | ipset-timeout yes | | ipset-timeout | 设置 ipset 超时功能启用 | 自动 | [yes] | ipset-timeout yes |
| domain-rules | 设置域名规则 | 无 | domain-rules /domain/ [-rules...]<br>[-c\|-speed-check-mode]:测速模式,参考 speed-check-mode 配置<br>[-a\|-address]:参考 address 配置<br>[-n\|-nameserver]:参考 nameserver 配置<br>[-p\|-ipset]参考ipset配置<br>[-d\|-dualstack-ip-selection]:参考 dualstack-ip-selection | domain-rules /www.example.com/ -speed-check-mode none | | domain-rules | 设置域名规则 | 无 | domain-rules /domain/ [-rules...]<br>[-c\|-speed-check-mode]:测速模式,参考 speed-check-mode 配置<br>[-a\|-address]:参考 address 配置<br>[-n\|-nameserver]:参考 nameserver 配置<br>[-p\|-ipset]参考ipset配置<br>[-d\|-dualstack-ip-selection]:参考 dualstack-ip-selection | domain-rules /www.example.com/ -speed-check-mode none |
| domain-set | 设置域名集合 | 无 | domain-set [options...]<br>[-n\|-name]:域名集合名称 <br>[-t\|-type]域名集合类型当前仅支持list格式为域名列表一行一个域名。<br>[-f\|-file]:域名集合文件路径。<br> 选项需要配合address, nameserver, ipset等需要指定域名的地方使用使用方式为 /domain-set:[name]/| domain-set -name set -type list -file /path/to/list <br> address /domain-set:set/1.2.4.8 |
| bogus-nxdomain | 假冒 IP 地址过滤 | 无 | [ip/subnet],可重复 | bogus-nxdomain 1.2.3.4/16 | | bogus-nxdomain | 假冒 IP 地址过滤 | 无 | [ip/subnet],可重复 | bogus-nxdomain 1.2.3.4/16 |
| ignore-ip | 忽略 IP 地址 | 无 | [ip/subnet],可重复 | ignore-ip 1.2.3.4/16 | | ignore-ip | 忽略 IP 地址 | 无 | [ip/subnet],可重复 | ignore-ip 1.2.3.4/16 |
| whitelist-ip | 白名单 IP 地址 | 无 | [ip/subnet],可重复 | whitelist-ip 1.2.3.4/16 | | whitelist-ip | 白名单 IP 地址 | 无 | [ip/subnet],可重复 | whitelist-ip 1.2.3.4/16 |
@@ -753,6 +698,31 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
* Windows系统默认使用mDNS解析地址如需要在windows下用使用smartdns解析则需要在主机名后面增加`.`表示使用DNS解析。如`ping smartdns.` * Windows系统默认使用mDNS解析地址如需要在windows下用使用smartdns解析则需要在主机名后面增加`.`表示使用DNS解析。如`ping smartdns.`
13. 域名集合如何使用?
为方便按集合配置域名,对于有/domain/的配置,可以指定域名集合,方便维护。具体方法为:
* 使用`domain-set`配置集合文件,如
```sh
domain-set -name ad -file /etc/smartdns/ad-list.conf
```
ad-list.conf的格式为一个域名一行
```
ad.com
site.com
```
* 在有/domain/配置的选项使用域名集合,只需要将`/domain/`配置为`/domain-set:[集合名称]/`即可,如:
```sh
address /domain-set:ad/#
domain-rules /domain-set:ad/ -a #
nameserver /domain-set:ad/server
...
```
## 编译 ## 编译
SmartDNS 提供了编译软件包的脚本(`package/build-pkg.sh`),支持编译 LuCI、Debian、OpenWrt 和 Optware 安装包。 SmartDNS 提供了编译软件包的脚本(`package/build-pkg.sh`),支持编译 LuCI、Debian、OpenWrt 和 Optware 安装包。

View File

@@ -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`. 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. 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** * **Check if the service is configured successfully**
@@ -260,54 +260,20 @@ https://github.com/pymumu/smartdns/releases
smartdns name = smartdns. 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 1. Start Service
Check the `Enable' in the configuration page to start SmartDNS server. Check the `Enable' in the configuration page to start SmartDNS server.
1. Note 1. Note
* If chinaDNS is already installed, it is recommended to configure the upstream of chinaDNS as SmartDNS. * 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.
* SmartDNS defaults to forwarding port 53 requests to the local port of SmartDNS, controlled by the `Redirect` configuration option. * 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 ### ASUS router native firmware / Merlin firmware
@@ -515,12 +481,13 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|server-tls|Upstream TLS DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tls 8.8.8.8:853 |server-tls|Upstream TLS DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tls 8.8.8.8:853
|server-https|Upstream HTTPS DNS server|None|Repeatable <br>`https://[host][:port]/path`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name<br>`[-http-host]`http header host. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-https https://cloudflare-dns.com/dns-query |server-https|Upstream HTTPS DNS server|None|Repeatable <br>`https://[host][:port]/path`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name<br>`[-http-host]`http header host. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-https https://cloudflare-dns.com/dns-query
|speed-check-mode|Speed mode|None|[ping\|tcp:[80]\|none]|speed-check-mode ping,tcp:80,tcp:443 |speed-check-mode|Speed mode|None|[ping\|tcp:[80]\|none]|speed-check-mode ping,tcp:80,tcp:443
|response-mode|First query response mode|first-ping|Mode: [fisrt-ping\|fastest-ip\|first-response]<br> [first-ping]: The fastest dns + ping response mode, DNS query delay + ping delay is the shortest;<br>[fastest-ip]: The fastest IP address mode, return the fastest ip address, may take some time to test speed. <br>[first-response]: The fastest response DNS result mode, the DNS query waiting time is the shortest. | response-mode first-ping | |response-mode|First query response mode|first-ping|Mode: [fisrt-ping\|fastest-ip\|fastest-response]<br> [first-ping]: The fastest dns + ping response mode, DNS query delay + ping delay is the shortest;<br>[fastest-ip]: The fastest IP address mode, return the fastest ip address, may take some time to test speed. <br>[fastest-response]: The fastest response DNS result mode, the DNS query waiting time is the shortest. | response-mode first-ping |
|address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4 |address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4
|nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office |nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office
|ipset|Domain IPSet|None|ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]], `-` for ignore|ipset /www.example.com/#4:dns4,#6:- |ipset|Domain IPSet|None|ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]], `-` for ignore|ipset /www.example.com/#4:dns4,#6:-
|ipset-timeout|ipset timeout enable|auto|[yes]|ipset-timeout yes |ipset-timeout|ipset timeout enable|auto|[yes]|ipset-timeout yes
|domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]<br>`[-c\|-speed-check-mode]`: set speed check modesame as parameter `speed-check-mode`<br>`[-a\|-address]`: same as parameter `address` <br>`[-n\|-nameserver]`: same as parameter `nameserver`<br>`[-p\|-ipset]`: same as parameter `ipset`<br>`[-d\|-dualstack-ip-selection]`: same as parameter `dualstack-ip-selection`|domain-rules /www.example.com/ -speed-check-mode none |domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]<br>`[-c\|-speed-check-mode]`: set speed check modesame as parameter `speed-check-mode`<br>`[-a\|-address]`: same as parameter `address` <br>`[-n\|-nameserver]`: same as parameter `nameserver`<br>`[-p\|-ipset]`: same as parameter `ipset`<br>`[-d\|-dualstack-ip-selection]`: same as parameter `dualstack-ip-selection`|domain-rules /www.example.com/ -speed-check-mode none
| domain-set | collection of domains|None| domain-set [options...]<br>[-n\|-name]name of set <br>[-t\|-type] [list]: set type, only support list, one domain per line <br>[-f\|-file]file path of domain set<br> used with address, nameserver, ipset, example: /domain-set:[name]/ | domain-set -name set -type list -file /path/to/list <br> address /domain-set:set/1.2.4.8 |
|bogus-nxdomain|bogus IP address|None|[IP/subnet], Repeatable| bogus-nxdomain 1.2.3.4/16 |bogus-nxdomain|bogus IP address|None|[IP/subnet], Repeatable| bogus-nxdomain 1.2.3.4/16
|ignore-ip|ignore ip address|None|[ip/subnet], Repeatable| ignore-ip 1.2.3.4/16 |ignore-ip|ignore ip address|None|[ip/subnet], Repeatable| ignore-ip 1.2.3.4/16
|whitelist-ip|ip whitelist|None|[ip/subnet], RepeatableWhen the filtering server responds IPs in the IP whitelist, only result in whitelist will be accepted| whitelist-ip 1.2.3.4/16 |whitelist-ip|ip whitelist|None|[ip/subnet], RepeatableWhen the filtering server responds IPs in the IP whitelist, only result in whitelist will be accepted| whitelist-ip 1.2.3.4/16
@@ -666,12 +633,37 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
```sh ```sh
dnsmasq-lease-file /var/lib/misc/dnsmasq.leases dnsmasq-lease-file /var/lib/misc/dnsmasq.leases
````\ ```
After the configuration is complete, you can directly use the host name to connect to the local machine. But need to pay attention: After the configuration is complete, you can directly use the host name to connect to the local machine. But need to pay attention:
* Windows system uses mDNS to resolve addresses by default. If you need to use smartdns to resolve addresses under Windows, you need to add `.` after the host name, indicating that DNS resolution is used. Such as `ping smartdns.` * Windows system uses mDNS to resolve addresses by default. If you need to use smartdns to resolve addresses under Windows, you need to add `.` after the host name, indicating that DNS resolution is used. Such as `ping smartdns.`
1. How to use the domain set?
To facilitate configuring domain names by set, for configurations with /domain/, you can specify a domain name set for easy maintenance. The specific method is:
* Use `domain-set` configuration domain set file:
````sh
domain-set -name ad -file /etc/smartdns/ad-list.conf
````
The format of ad-list.conf is one domain per line:
````
ad.com
site.com
````
* To use the domain set, you only need to configure `/domain/` to `/domain-set:[collection name]/`, such as:
````sh
address /domain-set:ad/#
domain-rules /domain-set:ad/ -a #
nameserver /domain-set:ad/server
...
````
## Compile ## Compile
smartdns contains scripts for compiling packages, supports compiling luci, debian, openwrt, opare installation packages, and can execute `package/build-pkg.sh` compilation. smartdns contains scripts for compiling packages, supports compiling luci, debian, openwrt, opare installation packages, and can execute `package/build-pkg.sh` compilation.

View File

@@ -219,3 +219,17 @@ log-level info
# [-n] -nameserver [group|-]: same as nameserver option # [-n] -nameserver [group|-]: same as nameserver option
# [-p] -ipset [ipset|-]: same as ipset option # [-p] -ipset [ipset|-]: same as ipset option
# [-d] -dualstack-ip-selection [yes|no]: same as dualstack-ip-selection option # [-d] -dualstack-ip-selection [yes|no]: same as dualstack-ip-selection option
# collection of domains
# the domain-set can be used with /domain/ for address, nameserver, ipset, etc.
# domain-set -name [set-name] -type list -file [/path/to/file]
# [-n] -name [set name]: domain set name
# [-t] -type [list]: domain set type, list only now
# [-f] -file [path/to/set]: file path of domain set
#
# example:
# domain-set -name domain-list -type list -file /etc/smartdns/domain-list.conf
# address /domain-set:domain-list/1.2.3.4
# nameserver /domain-set:domain-list/server-group
# ipset /domain-set:domain-list/ipset
# domain-rules /domain-set:domain-list/ -speed-check-mode ping

View File

@@ -1,6 +1,6 @@
Package: luci-app-smartdns Package: luci-app-smartdns
Version: git-18.201.27126-7bf0367-1 Version: git-18.201.27126-7bf0367-1
Depends: libc, smartdns Depends: libc, smartdns, luci-compat
Source: feeds/luci/applications/luci-app-smartdns Source: feeds/luci/applications/luci-app-smartdns
Section: luci Section: luci
Architecture: all Architecture: all

View File

@@ -38,46 +38,20 @@ end
function act_status() function act_status()
local e={} local e={}
local ipv6_server; 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") local dnsmasq_server = luci.sys.exec("uci get dhcp.@dnsmasq[0].server")
if e.local_port ~= nil then local auto_set_dnsmasq = smartdns.get_config_option("smartdns", "smartdns", "auto_set_dnsmasq", nil);
e.auto_set_dnsmasq = auto_set_dnsmasq
e.dnsmasq_server = dnsmasq_server
e.local_port = smartdns.get_config_option("smartdns", "smartdns", "port", nil);
if e.local_port ~= nil and e.local_port ~= "53" and auto_set_dnsmasq ~= nil and auto_set_dnsmasq == "1" then
local str;
str = "127.0.0.1#" .. e.local_port str = "127.0.0.1#" .. e.local_port
if string.sub(dnsmasq_server,1,string.len(str)) == str then if string.sub(dnsmasq_server,1,string.len(str)) ~= str then
e.dnsmasq_forward = 1 e.dnsmasq_redirect_failure = 1
end
end end
end end
e.running = is_running() e.running = is_running()
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")
luci.http.write_json(e) luci.http.write_json(e)
end end

View File

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

View File

@@ -45,9 +45,10 @@ o.datatype = "hostname"
o.rempty = false o.rempty = false
---- Port ---- Port
o = s:taboption("settings", Value, "port", translate("Local Port"), translate("Smartdns local server port")) o = s:taboption("settings", Value, "port", translate("Local Port"),
o.placeholder = 6053 translate("Smartdns local server port, smartdns will be automatically set as main dns when the port is 53."))
o.default = 6053 o.placeholder = 53
o.default = 53
o.datatype = "port" o.datatype = "port"
o.rempty = false o.rempty = false
@@ -92,19 +93,42 @@ o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "0" return Flag.cfgvalue(...) or "0"
end 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 ---- cache-size
o = s:taboption("settings", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size")) o = s:taboption("settings", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size"))
o.rempty = true 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 ---- rr-ttl
o = s:taboption("settings", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result.")) o = s:taboption("settings", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result."))
o.rempty = true o.rempty = true
@@ -121,7 +145,7 @@ o = s:taboption("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), tr
o.rempty = true o.rempty = true
---- rr-ttl-reply-max ---- 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("Reply Domain TTL Max"), translate("Reply maximum TTL for all domain result."))
o.rempty = true o.rempty = true
---- second dns server ---- second dns server
@@ -207,7 +231,7 @@ o.cfgvalue = function(...)
end end
---- Force AAAA SOA ---- Force AAAA SOA
o = s:taboption("seconddns", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA.")) o = s:taboption("seconddns", Flag, "seconddns_force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
o.rmempty = false o.rmempty = false
o.default = o.disabled o.default = o.disabled
o.cfgvalue = function(...) o.cfgvalue = function(...)

View File

@@ -6,23 +6,9 @@ XHR.poll(3, '<%=luci.dispatcher.build_url("admin", "services", "smartdns", "stat
var links = ""; var links = "";
if (data.running) { if (data.running) {
links = '<b><font color=green>SmartDNS - <%:RUNNING%></font></b></em>'; links = '<b><font color=green>SmartDNS - <%:RUNNING%></font></b></em>';
if (data.redirect) { if (data.dnsmasq_redirect_failure == 1) {
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>" links += "<br></br><b><font color=red><%:Dnsmasq Forwared To Smartdns Failure%></font></b>"
} }
}
}
} else { } else {
links = '<b><font color=red>SmartDNS - <%:NOT RUNNING%></font></b>'; links = '<b><font color=red>SmartDNS - <%:NOT RUNNING%></font></b>';
} }

View File

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

View File

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

View File

@@ -21,6 +21,8 @@
'require fs'; 'require fs';
'require uci'; 'require uci';
'require form'; 'require form';
'require view';
'require poll';
'require rpc'; 'require rpc';
var conf = 'smartdns'; var conf = 'smartdns';
@@ -31,7 +33,7 @@ var callServiceList = rpc.declare({
expect: { '': {} } expect: { '': {} }
}); });
function getPidOfSmartdns() { function getServiceStatus() {
return L.resolveDefault(callServiceList(conf), {}) return L.resolveDefault(callServiceList(conf), {})
.then(function (res) { .then(function (res) {
var isrunning = false; var isrunning = false;
@@ -42,43 +44,19 @@ function getPidOfSmartdns() {
}); });
} }
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 "";
}
});
}
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 "";
}
});
}
function smartdnsServiceStatus() { function smartdnsServiceStatus() {
return Promise.all([ return Promise.all([
getPidOfSmartdns(), getServiceStatus()
getIPTablesRedirect(),
getIP6TablesRedirect()
]); ]);
} }
function smartdnsRenderStatus(res) { function smartdnsRenderStatus(res) {
var renderHTML = ""; var renderHTML = "";
var isRunning = res[0]; var isRunning = res[0];
var ipt = res[1];
var ip6t = res[2];
var serverPort = uci.get_first('smartdns', 'smartdns', 'port'); var autoSetDnsmasq = uci.get_first('smartdns', 'smartdns', 'auto_set_dnsmasq');
var redirectMode = uci.get_first('smartdns', 'smartdns', 'redirect'); var smartdnsPort = uci.get_first('smartdns', 'smartdns', 'port');
var ipv6Enabled = uci.get_first('smartdns', 'smartdns', 'ipv6_server'); var dnsmasqServer = uci.get_first('dhcp', 'dnsmasq', 'server');
if (isRunning) { if (isRunning) {
renderHTML += "<span style=\"color:green;font-weight:bold\">SmartDNS - " + _("RUNNING") + "</span>"; renderHTML += "<span style=\"color:green;font-weight:bold\">SmartDNS - " + _("RUNNING") + "</span>";
@@ -87,39 +65,24 @@ function smartdnsRenderStatus(res) {
return renderHTML; return renderHTML;
} }
if (redirectMode === "dnsmasq-upstream") { if (autoSetDnsmasq === '1' && smartdnsPort != '53') {
var matchLine = "127.0.0.1#" + serverPort; var matchLine = "127.0.0.1#" + smartdnsPort;
var dnsmasqServer = uci.get_first('dhcp', 'dnsmasq', 'server') || "";
if (dnsmasqServer.indexOf(matchLine) < 0) { uci.unload('dhcp');
uci.load('dhcp');
if (dnsmasqServer == undefined || dnsmasqServer.indexOf(matchLine) < 0) {
renderHTML += "<br /><span style=\"color:red;font-weight:bold\">" + _("Dnsmasq Forwared To Smartdns Failure") + "</span>"; 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 renderHTML;
} }
return L.view.extend({ return view.extend({
load: function () { load: function () {
return Promise.all([ return Promise.all([
uci.load('dhcp'),
uci.load('smartdns'), uci.load('smartdns'),
uci.load('dhcp')
]); ]);
}, },
render: function (stats) { render: function (stats) {
@@ -133,12 +96,17 @@ return L.view.extend({
s = m.section(form.NamedSection, '_status'); s = m.section(form.NamedSection, '_status');
s.anonymous = true; s.anonymous = true;
s.render = function (section_id) { s.render = function (section_id) {
L.Poll.add(function () { var renderStatus = function () {
return L.resolveDefault(smartdnsServiceStatus()).then(function (res) { return L.resolveDefault(smartdnsServiceStatus()).then(function (res) {
var view = document.getElementById("service_status"); var view = document.getElementById("service_status");
if (view == null) {
return;
}
view.innerHTML = smartdnsRenderStatus(res); view.innerHTML = smartdnsRenderStatus(res);
}); });
}); }
poll.add(renderStatus, 1);
return E('div', { class: 'cbi-map' }, return E('div', { class: 'cbi-map' },
E('div', { class: 'cbi-section' }, [ E('div', { class: 'cbi-section' }, [
@@ -156,10 +124,9 @@ return L.view.extend({
s.tab("seconddns", _("Second Server Settings")); s.tab("seconddns", _("Second Server Settings"));
s.tab("custom", _("Custom Settings")); s.tab("custom", _("Custom Settings"));
// Eanble;
o = s.taboption("settings", form.Flag, "enabled", _("Enable"), _("Enable or disable smartdns server")); o = s.taboption("settings", form.Flag, "enabled", _("Enable"), _("Enable or disable smartdns server"));
o.rmempty = false;
o.default = o.disabled; o.default = o.disabled;
o.rempty = false;
// server name; // server name;
o = s.taboption("settings", form.Value, "server_name", _("Server Name"), _("Smartdns server name")); o = s.taboption("settings", form.Value, "server_name", _("Server Name"), _("Smartdns server name"));
@@ -168,9 +135,10 @@ return L.view.extend({
o.rempty = false; o.rempty = false;
// Port; // Port;
o = s.taboption("settings", form.Value, "port", _("Local Port"), _("Smartdns local server port")); o = s.taboption("settings", form.Value, "port", _("Local Port"),
o.placeholder = 6053; _("Smartdns local server port, smartdns will be automatically set as main dns when the port is 53."));
o.default = 6053; o.placeholder = 53;
o.default = 53;
o.datatype = "port"; o.datatype = "port";
o.rempty = false; o.rempty = false;
@@ -202,19 +170,30 @@ return L.view.extend({
o.rmempty = false; o.rmempty = false;
o.default = o.enabled; 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; // cache-size;
o = s.taboption("settings", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size")); o = s.taboption("settings", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size"));
o.rempty = true; 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; // rr-ttl;
o = s.taboption("settings", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result.")); o = s.taboption("settings", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result."));
o.rempty = true; o.rempty = true;
@@ -233,8 +212,8 @@ return L.view.extend({
o.rempty = true; o.rempty = true;
// rr-ttl-reply-max; // rr-ttl-reply-max;
o = s.taboption("settings", form.Value, "rr_ttl_reply_max", _("Domain Reply TTL Max"), o = s.taboption("settings", form.Value, "rr_ttl_reply_max", _("Reply Domain TTL Max"),
_("Maximum Reply TTL for all domain result.")); _("Reply maximum TTL for all domain result."));
o.rempty = true; o.rempty = true;
// second dns server; // second dns server;
@@ -304,7 +283,7 @@ return L.view.extend({
o.default = o.disabled; o.default = o.disabled;
// Force AAAA SOA // Force AAAA SOA
o = s.taboption("seconddns", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); o = s.taboption("seconddns", form.Flag, "seconddns_force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
o.rmempty = false; o.rmempty = false;
o.default = o.disabled; o.default = o.disabled;

View File

@@ -36,17 +36,17 @@ set_forward_dnsmasq()
{ {
local PORT="$1" local PORT="$1"
addr="127.0.0.1#$PORT" addr="127.0.0.1#$PORT"
OLD_SERVER="$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)" # space in suffix is important
OLD_SERVER="$(uci -q get dhcp.@dnsmasq[0].server) "
if echo "$OLD_SERVER" | grep "^$addr " >/dev/null 2>&1; then if echo "$OLD_SERVER" | grep "^$addr " >/dev/null 2>&1; then
return return
fi fi
uci delete dhcp.@dnsmasq[0].server 2>/dev/null
uci add_list dhcp.@dnsmasq[0].server="$addr" uci -q delete dhcp.@dnsmasq[0].server
for server in $OLD_SERVER; do uci -q add_list dhcp.@dnsmasq[0].server="$addr"
[ "$server" = "$addr" ] && continue uci -q set dhcp.@dnsmasq[0].noresolv=1
uci add_list dhcp.@dnsmasq[0].server="$server" uci -q set dhcp.@dnsmasq[0].rebind_protection=0
done uci -q set dhcp.@dnsmasq[0].domainneeded=0
uci set dhcp.@dnsmasq[0].noresolv=1
uci commit dhcp uci commit dhcp
/etc/init.d/dnsmasq restart /etc/init.d/dnsmasq restart
} }
@@ -54,46 +54,59 @@ set_forward_dnsmasq()
stop_forward_dnsmasq() stop_forward_dnsmasq()
{ {
local OLD_PORT="$1" local OLD_PORT="$1"
local norestart="$2"
addr="127.0.0.1#$OLD_PORT" addr="127.0.0.1#$OLD_PORT"
OLD_SERVER="$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)" OLD_SERVER="$(uci -q get dhcp.@dnsmasq[0].server) "
if ! echo "$OLD_SERVER" | grep "^$addr " >/dev/null 2>&1; then if ! echo "$OLD_SERVER" | grep "^$addr " >/dev/null 2>&1; then
return return
fi fi
uci del_list dhcp.@dnsmasq[0].server="$addr" 2>/dev/null uci -q delete dhcp.@dnsmasq[0].server
addrlist="$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)" uci -q delete dhcp.@dnsmasq[0].noresolv
[ -z "$addrlist" ] && { uci -q set dhcp.@dnsmasq[0].rebind_protection=1
uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null uci -q set dhcp.@dnsmasq[0].domainneeded=1
uci commit dhcp
[ "$norestart" != "1" ] && /etc/init.d/dnsmasq restart
} }
set_main_dns()
{
local hostip
hostip="$(uci -q get network.lan.ipaddr)"
dnsmasq_port="$(uci -q get dhcp.@dnsmasq[0].port)"
[ -z "$dnsmasq_port" ] && dnsmasq_port="53"
[ -z "$hostip" ] && return
[ "$dnsmasq_port" = "53" ] && {
uci -q set dhcp.@dnsmasq[0].port=0
uci -q set dhcp.lan.dhcp_option="6,$hostip"
}
# for some third-party firmware
redir_dns="$(uci -q get dhcp.@dnsmasq[0].dns_redirect)"
[ "$redir_dns" = "1" ] && {
uci -q set dhcp.@dnsmasq[0].dns_redirect=0
uci -q set dhcp.@dnsmasq[0].old_dns_redirect=1
}
uci commit dhcp uci commit dhcp
/etc/init.d/dnsmasq restart /etc/init.d/dnsmasq restart
} }
set_iptable() stop_main_dns()
{ {
local ipv6_server=$1 local norestart="$1"
local tcp_server=$2 dnsmasq_port="$(uci -q get dhcp.@dnsmasq[0].port)"
redir_dns="$(uci -q get dhcp.@dnsmasq[0].old_dns_redirect)"
IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}')" [ "$dnsmasq_port" != "0" ] && return
for IP in $IPS [ "$redir_dns" = "1" ] && {
do uci -q set dhcp.@dnsmasq[0].dns_redirect=1
if [ "$tcp_server" = "1" ]; then uci -q delete dhcp.@dnsmasq[0].old_dns_redirect
iptables -t nat -A PREROUTING -p tcp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" >/dev/null 2>&1 }
fi uci -q delete dhcp.@dnsmasq[0].port
iptables -t nat -A PREROUTING -p udp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" >/dev/null 2>&1 uci -q delete dhcp.lan.dhcp_option
done uci commit dhcp
[ "$norestart" != "1" ] && /etc/init.d/dnsmasq restart
[ "$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() clear_iptable()
@@ -115,7 +128,6 @@ clear_iptable()
ip6tables -t nat -D PREROUTING -p udp -d "$IP" --dport 53 -j REDIRECT --to-ports "$OLD_PORT" >/dev/null 2>&1 ip6tables -t nat -D PREROUTING -p udp -d "$IP" --dport 53 -j REDIRECT --to-ports "$OLD_PORT" >/dev/null 2>&1
ip6tables -t nat -D PREROUTING -p tcp -d "$IP" --dport 53 -j REDIRECT --to-ports "$OLD_PORT" >/dev/null 2>&1 ip6tables -t nat -D PREROUTING -p tcp -d "$IP" --dport 53 -j REDIRECT --to-ports "$OLD_PORT" >/dev/null 2>&1
done done
} }
service_triggers() { service_triggers() {
@@ -241,8 +253,8 @@ load_second_server()
config_get_bool seconddns_no_cache "$section" "seconddns_no_cache" "0" config_get_bool seconddns_no_cache "$section" "seconddns_no_cache" "0"
[ "$seconddns_no_cache" = "1" ] && ARGS="$ARGS -no-cache" [ "$seconddns_no_cache" = "1" ] && ARGS="$ARGS -no-cache"
config_get_bool force_aaaa_soa "$section" "force_aaaa_soa" "0" config_get_bool seconddns_force_aaaa_soa "$section" "seconddns_force_aaaa_soa" "0"
[ "$force_aaaa_soa" = "1" ] && ARGS="$ARGS -force-aaaa-soa" [ "$seconddns_force_aaaa_soa" = "1" ] && ARGS="$ARGS -force-aaaa-soa"
config_get ipv6_server "$section" "ipv6_server" "1" config_get ipv6_server "$section" "ipv6_server" "1"
if [ "$ipv6_server" = "1" ]; then if [ "$ipv6_server" = "1" ]; then
@@ -260,6 +272,14 @@ load_service()
{ {
local section="$1" local section="$1"
args="" args=""
dnsmasq_lease_file="$(uci -q get dhcp.@dnsmasq[0].leasefile)"
dnsmasq_port="$(uci -q get dhcp.@dnsmasq[0].port)"
resolve_file="$(uci -q get dhcp.@dnsmasq[0].resolvfile)"
[ -z "$dnsmasq_lease_file" ] && dnsmasq_lease_file="/tmp/dhcp.leases"
[ -z "$dnsmasq_port" ] && dnsmasq_port="53"
[ -z "$resolve_file" ] && resolve_file="/tmp/resolv.conf.d/resolv.conf.auto"
qtype_soa_list=""
mkdir -p $SMARTDNS_VAR_CONF_DIR mkdir -p $SMARTDNS_VAR_CONF_DIR
rm -f $SMARTDNS_CONF_TMP rm -f $SMARTDNS_CONF_TMP
@@ -272,22 +292,10 @@ load_service()
config_get coredump "$section" "coredump" "0" config_get coredump "$section" "coredump" "0"
[ "$coredump" = "1" ] && COREDUMP="1" [ "$coredump" = "1" ] && COREDUMP="1"
config_get port "$section" "port" "6053" config_get port "$section" "port" "53"
config_get ipv6_server "$section" "ipv6_server" "1" config_get ipv6_server "$section" "ipv6_server" "1"
config_get tcp_server "$section" "tcp_server" "1" config_get tcp_server "$section" "tcp_server" "1"
if [ "$ipv6_server" = "1" ]; then
conf_append "bind" "[::]:$port"
else
conf_append "bind" ":$port"
fi
[ "$tcp_server" = "1" ] && {
if [ "$ipv6_server" = "1" ]; then
conf_append "bind-tcp" "[::]:$port"
else
conf_append "bind-tcp" ":$port"
fi
}
config_get dualstack_ip_selection "$section" "dualstack_ip_selection" "0" config_get dualstack_ip_selection "$section" "dualstack_ip_selection" "0"
[ "$dualstack_ip_selection" = "0" ] && conf_append "dualstack-ip-selection" "no" [ "$dualstack_ip_selection" = "0" ] && conf_append "dualstack-ip-selection" "no"
@@ -297,11 +305,20 @@ load_service()
config_get serve_expired "$section" "serve_expired" "0" config_get serve_expired "$section" "serve_expired" "0"
[ "$serve_expired" = "1" ] && conf_append "serve-expired" "yes" [ "$serve_expired" = "1" ] && conf_append "serve-expired" "yes"
SMARTDNS_PORT="$port"
config_get cache_size "$section" "cache_size" "" config_get cache_size "$section" "cache_size" ""
[ -z "$cache_size" ] || conf_append "cache-size" "$cache_size" [ -z "$cache_size" ] || conf_append "cache-size" "$cache_size"
config_get resolve_local_hostnames "$section" "resolve_local_hostnames" "1"
[ "$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"
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" "1"
config_get rr_ttl "$section" "rr_ttl" "" config_get rr_ttl "$section" "rr_ttl" ""
[ -z "$rr_ttl" ] || conf_append "rr-ttl" "$rr_ttl" [ -z "$rr_ttl" ] || conf_append "rr-ttl" "$rr_ttl"
@@ -326,34 +343,85 @@ load_service()
config_get log_file "$section" "log_file" "" config_get log_file "$section" "log_file" ""
[ -z "$log_file" ] || conf_append "log-file" "$log_file" [ -z "$log_file" ] || conf_append "log-file" "$log_file"
config_get redirect "$section" "redirect" "none" config_get redirect "$section" "redirect" ""
config_get old_redirect "$section" "old_redirect" "none"
config_get old_port "$section" "old_port" "0" config_get old_port "$section" "old_port" "0"
config_get old_enabled "$section" "old_enabled" "0" config_get old_enabled "$section" "old_enabled" "0"
config_get old_auto_set_dnsmasq "$section" "old_auto_set_dnsmasq" "0"
if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$SMARTDNS_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then [ -z "$qtype_soa_list" ] || conf_append "force-qtype-SOA" "$qtype_soa_list"
[ "$old_redirect" = "none" ] || { [ -e "$resolve_file" ] && conf_append "resolv-file" "$resolve_file"
[ "$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
[ "$redirect" = "redirect" ] && {
clear_iptable "$port"
clear_iptable "$old_port"
uci -q delete smartdns.@smartdns[0].port
port="53"
} }
[ "$redirect" = "dnsmasq-upstream" ] && {
stop_forward_dnsmasq "$port"
stop_forward_dnsmasq "$old_port"
auto_set_dnsmasq="1"
uci -q set smartdns.@smartdns[0].auto_set_dnsmasq="1"
}
[ "$redirect" = "none" ] && {
auto_set_dnsmasq="0"
uci -q set smartdns.@smartdns[0].auto_set_dnsmasq="0"
}
uci -q delete smartdns.@smartdns[0].redirect
uci -q delete smartdns.@smartdns[0].old_redirect
fi fi
uci delete smartdns.@smartdns[0].old_redirect 2>/dev/null uci -q delete smartdns.@smartdns[0].old_port
uci delete smartdns.@smartdns[0].old_port 2>/dev/null uci -q delete smartdns.@smartdns[0].old_enabled
uci delete smartdns.@smartdns[0].old_enabled 2>/dev/null uci -q delete smartdns.@smartdns[0].old_auto_set_dnsmasq
uci add_list smartdns.@smartdns[0].old_redirect="$redirect" 2>/dev/null uci -q set smartdns.@smartdns[0].old_port="$port"
uci add_list smartdns.@smartdns[0].old_port="$SMARTDNS_PORT" 2>/dev/null uci -q set smartdns.@smartdns[0].old_enabled="$enabled"
uci add_list smartdns.@smartdns[0].old_enabled="$enabled" 2>/dev/null uci -q set smartdns.@smartdns[0].old_auto_set_dnsmasq="$auto_set_dnsmasq"
uci commit smartdns uci commit smartdns
[ "$enabled" -gt 0 ] || return 1 # disable service
[ "$enabled" = "0" ] && {
[ "$old_enabled" = "0" ] && return 1
[ "$old_port" = "53" ] && stop_main_dns "0"
[ "$old_port" != "53" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0"
return 1
}
if [ "$redirect" = "redirect" ]; then # change port
set_iptable $ipv6_server $tcp_server [ "$old_port" != "$port" ] && {
elif [ "$redirect" = "dnsmasq-upstream" ]; then [ "$old_port" = "53" ] && {
set_forward_dnsmasq "$SMARTDNS_PORT" no_restart_dnsmasq="1"
[ "$auto_set_dnsmasq" = "0" ] && no_restart_dnsmasq="0"
stop_main_dns "$no_restart_dnsmasq"
}
[ "$old_port" != "53" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "1"
}
# start service
[ "$port" = "53" ] && set_main_dns
[ "$port" != "53" ] && {
[ "$auto_set_dnsmasq" = "1" ] && set_forward_dnsmasq "$port"
[ "$auto_set_dnsmasq" = "0" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0"
}
if [ "$ipv6_server" = "1" ]; then
conf_append "bind" "[::]:$port"
else
conf_append "bind" ":$port"
fi fi
[ "$tcp_server" = "1" ] && {
if [ "$ipv6_server" = "1" ]; then
conf_append "bind-tcp" "[::]:$port"
else
conf_append "bind-tcp" ":$port"
fi
}
load_second_server $section load_second_server $section
config_foreach load_server "server" config_foreach load_server "server"
@@ -381,6 +449,28 @@ load_service()
procd_close_instance procd_close_instance
} }
unload_service()
{
local section="$1"
dnsmasq_port="$(uci -q get dhcp.@dnsmasq[0].port)"
config_get port "$section" "port" "53"
config_get old_port "$section" "old_port" "0"
config_get auto_set_dnsmasq "$section" "auto_set_dnsmasq" "0"
[ -z "${dnsmasq_port}" ] && dnsmasq_port="53"
[ "$enabled" = "1" ] && {
[ "$old_enabled" = "0" ] && return 1
[ "$old_port" = "53" ] && stop_main_dns "0"
[ "$old_port" != "53" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0"
}
}
service_stopped()
{
config_load "smartdns"
config_foreach unload_service "smartdns"
}
start_service() start_service()
{ {
config_load "smartdns" config_load "smartdns"

View File

@@ -23,9 +23,9 @@ ifndef CFLAGS
CFLAGS =-O2 -g -Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables -Wmissing-prototypes -Wshadow -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough CFLAGS =-O2 -g -Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables -Wmissing-prototypes -Wshadow -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough
endif endif
override CFLAGS +=-Iinclude override CFLAGS +=-Iinclude
override CFLAGS += -DBASE_FILE_NAME=\"$(notdir $<)\" override CFLAGS += -DBASE_FILE_NAME='"$(notdir $<)"'
ifdef VER ifdef VER
override CFLAGS += -DSMARTDNS_VERION=\"$(VER)\" override CFLAGS += -DSMARTDNS_VERION='"$(VER)"'
endif endif
CXXFLAGS=-O2 -g -Wall -std=c++11 CXXFLAGS=-O2 -g -Wall -std=c++11

View File

@@ -3010,11 +3010,6 @@ static int _dns_client_query_setup_default_ecs(struct dns_query_struct *query)
static int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_query_options *options) static int _dns_client_query_parser_options(struct dns_query_struct *query, struct dns_query_options *options)
{ {
if (options == NULL) {
_dns_client_query_setup_default_ecs(query);
return 0;
}
if (options->enable_flag & DNS_QUEY_OPTION_ECS_IP) { if (options->enable_flag & DNS_QUEY_OPTION_ECS_IP) {
struct sockaddr_storage addr; struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr); socklen_t addr_len = sizeof(addr);
@@ -3069,6 +3064,10 @@ static int _dns_client_query_parser_options(struct dns_query_struct *query, stru
query->ecs.enable = 1; query->ecs.enable = 1;
} }
if (query->ecs.enable == 0) {
_dns_client_query_setup_default_ecs(query);
}
return 0; return 0;
} }

View File

@@ -32,6 +32,7 @@
#define DEFAULT_DNS_CACHE_SIZE 512 #define DEFAULT_DNS_CACHE_SIZE 512
#define DNS_MAX_REPLY_IP_NUM 8 #define DNS_MAX_REPLY_IP_NUM 8
#define DNS_RESOLV_FILE "/etc/resolv.conf"
/* ipset */ /* ipset */
struct dns_ipset_table { struct dns_ipset_table {
@@ -41,6 +42,9 @@ static struct dns_ipset_table dns_ipset_table;
struct dns_qtype_soa_table dns_qtype_soa_table; struct dns_qtype_soa_table dns_qtype_soa_table;
struct dns_domain_set_rule_table dns_domain_set_rule_table;
struct dns_domain_set_name_table dns_domain_set_name_table;
/* dns groups */ /* dns groups */
struct dns_group_table dns_group_table; struct dns_group_table dns_group_table;
@@ -133,6 +137,7 @@ char dns_conf_user[DNS_CONF_USRNAME_LEN];
int dns_save_fail_packet; int dns_save_fail_packet;
char dns_save_fail_packet_dir[DNS_MAX_PATH]; char dns_save_fail_packet_dir[DNS_MAX_PATH];
char dns_resolv_file[DNS_MAX_PATH];
/* ECS */ /* ECS */
struct dns_edns_client_subnet dns_conf_ipv4_ecs; struct dns_edns_client_subnet dns_conf_ipv4_ecs;
@@ -140,6 +145,62 @@ struct dns_edns_client_subnet dns_conf_ipv6_ecs;
char dns_conf_sni_proxy_ip[DNS_MAX_IPLEN]; char dns_conf_sni_proxy_ip[DNS_MAX_IPLEN];
static void *_new_dns_rule(enum domain_rule domain_rule)
{
struct dns_rule *rule;
int size = 0;
if (domain_rule >= DOMAIN_RULE_MAX) {
return NULL;
}
switch (domain_rule) {
case DOMAIN_RULE_FLAGS:
size = sizeof(struct dns_rule_flags);
break;
case DOMAIN_RULE_ADDRESS_IPV4:
size = sizeof(struct dns_rule_address_IPV4);
break;
case DOMAIN_RULE_ADDRESS_IPV6:
size = sizeof(struct dns_rule_address_IPV6);
break;
case DOMAIN_RULE_IPSET:
case DOMAIN_RULE_IPSET_IPV4:
case DOMAIN_RULE_IPSET_IPV6:
size = sizeof(struct dns_ipset_rule);
break;
case DOMAIN_RULE_NAMESERVER:
size = sizeof(struct dns_nameserver_rule);
break;
case DOMAIN_RULE_CHECKSPEED:
size = sizeof(struct dns_domain_check_orders);
break;
default:
return NULL;
}
rule = malloc(size);
if (!rule) {
return NULL;
}
memset(rule, 0, size);
rule->rule = domain_rule;
atomic_set(&rule->refcnt, 1);
return rule;
}
static void _dns_rule_get(struct dns_rule *rule)
{
atomic_inc(&rule->refcnt);
}
static void _dns_rule_put(struct dns_rule *rule)
{
if (atomic_dec_and_test(&rule->refcnt)) {
free(rule);
}
}
static int _get_domain(char *value, char *domain, int max_dmain_size, char **ptr_after_domain) static int _get_domain(char *value, char *domain, int max_dmain_size, char **ptr_after_domain)
{ {
char *begin = NULL; char *begin = NULL;
@@ -429,7 +490,8 @@ static int _config_domain_iter_free(void *data, const unsigned char *key, uint32
continue; continue;
} }
free(domain_rule->rules[i]); _dns_rule_put(domain_rule->rules[i]);
domain_rule->rules[i] = NULL;
} }
free(domain_rule); free(domain_rule);
@@ -456,6 +518,69 @@ static void _config_address_destroy(radix_node_t *node, void *cbctx)
node->data = NULL; node->data = NULL;
} }
static int _config_domain_set_rule_add_ext(char *set_name, enum domain_rule type, void *rule, unsigned int flags, int is_clear_flag)
{
struct dns_domain_set_rule *set_rule = NULL;
struct dns_domain_set_rule_list *set_rule_list = NULL;
uint32_t key = 0;
if (set_name == NULL) {
return -1;
}
set_rule = malloc(sizeof(struct dns_domain_set_rule));
if (set_rule == NULL) {
goto errout;
}
memset(set_rule, 0, sizeof(struct dns_domain_set_rule));
set_rule->type = type;
set_rule->rule = rule;
set_rule->flags = flags;
set_rule->is_clear_flag = is_clear_flag;
if (rule) {
_dns_rule_get(rule);
}
key = hash_string(set_name);
hash_for_each_possible(dns_domain_set_rule_table.rule_list, set_rule_list, node, key)
{
if (strncmp(set_rule_list->domain_set, set_name, DNS_MAX_CNAME_LEN) == 0) {
break;
}
}
if (set_rule_list == NULL) {
set_rule_list = malloc(sizeof(struct dns_domain_set_rule_list));
if (set_rule_list == NULL) {
goto errout;
}
memset(set_rule_list, 0, sizeof(struct dns_domain_set_rule_list));
INIT_LIST_HEAD(&set_rule_list->domain_ruls_list);
safe_strncpy(set_rule_list->domain_set, set_name, DNS_MAX_CNAME_LEN);
hash_add(dns_domain_set_rule_table.rule_list, &set_rule_list->node, key);
}
list_add_tail(&set_rule->list, &set_rule_list->domain_ruls_list);
return 0;
errout:
if (set_rule) {
free(set_rule);
}
return -1;
}
static int _config_domian_set_rule_flags(char *set_name, unsigned int flags, int is_clear_flag)
{
return _config_domain_set_rule_add_ext(set_name, DOMAIN_RULE_FLAGS, NULL, flags, is_clear_flag);
}
static int _config_domain_set_rule_add(char *set_name, enum domain_rule type, void *rule)
{
return _config_domain_set_rule_add_ext(set_name, type, rule, 0, 0);
}
static int _config_domain_rule_add(char *domain, enum domain_rule type, void *rule) static int _config_domain_rule_add(char *domain, enum domain_rule type, void *rule)
{ {
struct dns_domain_rule *domain_rule = NULL; struct dns_domain_rule *domain_rule = NULL;
@@ -471,6 +596,11 @@ static int _config_domain_rule_add(char *domain, enum domain_rule type, void *ru
tlog(TLOG_ERROR, "domain name %s too long", domain); tlog(TLOG_ERROR, "domain name %s too long", domain);
goto errout; goto errout;
} }
if (strncmp(domain, "domain-set:", sizeof("domain-set:") - 1) == 0) {
return _config_domain_set_rule_add(domain + sizeof("domain-set:") - 1, type, rule);
}
reverse_string(domain_key, domain, len, 1); reverse_string(domain_key, domain, len, 1);
domain_key[len] = '.'; domain_key[len] = '.';
len++; len++;
@@ -493,11 +623,12 @@ static int _config_domain_rule_add(char *domain, enum domain_rule type, void *ru
/* add new rule to domain */ /* add new rule to domain */
if (domain_rule->rules[type]) { if (domain_rule->rules[type]) {
free(domain_rule->rules[type]); _dns_rule_put(domain_rule->rules[type]);
domain_rule->rules[type] = NULL; domain_rule->rules[type] = NULL;
} }
domain_rule->rules[type] = rule; domain_rule->rules[type] = rule;
_dns_rule_get(rule);
/* update domain rule */ /* update domain rule */
if (add_domain_rule) { if (add_domain_rule) {
@@ -527,6 +658,10 @@ static int _config_domain_rule_flag_set(char *domain, unsigned int flag, unsigne
char domain_key[DNS_MAX_CONF_CNAME_LEN]; char domain_key[DNS_MAX_CONF_CNAME_LEN];
int len = 0; int len = 0;
if (strncmp(domain, "domain-set:", sizeof("domain-set:") - 1) == 0) {
return _config_domian_set_rule_flags(domain + sizeof("domain-set:") - 1, flag, is_clear);
}
len = strlen(domain); len = strlen(domain);
if (len >= (int)sizeof(domain_key)) { if (len >= (int)sizeof(domain_key)) {
tlog(TLOG_ERROR, "domain %s too long", domain); tlog(TLOG_ERROR, "domain %s too long", domain);
@@ -550,13 +685,12 @@ static int _config_domain_rule_flag_set(char *domain, unsigned int flag, unsigne
/* add new rule to domain */ /* add new rule to domain */
if (domain_rule->rules[DOMAIN_RULE_FLAGS] == NULL) { if (domain_rule->rules[DOMAIN_RULE_FLAGS] == NULL) {
rule_flags = malloc(sizeof(*rule_flags)); rule_flags = _new_dns_rule(DOMAIN_RULE_FLAGS);
memset(rule_flags, 0, sizeof(*rule_flags));
rule_flags->flags = 0; rule_flags->flags = 0;
domain_rule->rules[DOMAIN_RULE_FLAGS] = rule_flags; domain_rule->rules[DOMAIN_RULE_FLAGS] = (struct dns_rule *)rule_flags;
} }
rule_flags = domain_rule->rules[DOMAIN_RULE_FLAGS]; rule_flags = (struct dns_rule_flags *)domain_rule->rules[DOMAIN_RULE_FLAGS];
if (is_clear == false) { if (is_clear == false) {
rule_flags->flags |= flag; rule_flags->flags |= flag;
} else { } else {
@@ -668,7 +802,7 @@ static int _conf_domain_rule_ipset(char *domain, const char *ipsetname)
goto errout; goto errout;
} }
ipset_rule = malloc(sizeof(*ipset_rule)); ipset_rule = _new_dns_rule(type);
if (ipset_rule == NULL) { if (ipset_rule == NULL) {
goto errout; goto errout;
} }
@@ -678,6 +812,7 @@ static int _conf_domain_rule_ipset(char *domain, const char *ipsetname)
if (_config_domain_rule_add(domain, type, ipset_rule) != 0) { if (_config_domain_rule_add(domain, type, ipset_rule) != 0) {
goto errout; goto errout;
} }
_dns_rule_put(&ipset_rule->head);
} }
goto clear; goto clear;
@@ -686,7 +821,7 @@ errout:
tlog(TLOG_ERROR, "add ipset %s failed", ipsetname); tlog(TLOG_ERROR, "add ipset %s failed", ipsetname);
if (ipset_rule) { if (ipset_rule) {
free(ipset_rule); _dns_rule_put(&ipset_rule->head);
} }
clear: clear:
@@ -718,9 +853,9 @@ errout:
static int _conf_domain_rule_address(char *domain, const char *domain_address) static int _conf_domain_rule_address(char *domain, const char *domain_address)
{ {
struct dns_address_IPV4 *address_ipv4 = NULL; struct dns_rule_address_IPV4 *address_ipv4 = NULL;
struct dns_address_IPV6 *address_ipv6 = NULL; struct dns_rule_address_IPV6 *address_ipv6 = NULL;
void *address = NULL; struct dns_rule *address = NULL;
char ip[MAX_IP_LEN]; char ip[MAX_IP_LEN];
int port = 0; int port = 0;
struct sockaddr_storage addr; struct sockaddr_storage addr;
@@ -775,7 +910,7 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
switch (addr.ss_family) { switch (addr.ss_family) {
case AF_INET: { case AF_INET: {
struct sockaddr_in *addr_in = NULL; struct sockaddr_in *addr_in = NULL;
address_ipv4 = malloc(sizeof(*address_ipv4)); address_ipv4 = _new_dns_rule(DOMAIN_RULE_ADDRESS_IPV4);
if (address_ipv4 == NULL) { if (address_ipv4 == NULL) {
goto errout; goto errout;
} }
@@ -783,27 +918,27 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
addr_in = (struct sockaddr_in *)&addr; addr_in = (struct sockaddr_in *)&addr;
memcpy(address_ipv4->ipv4_addr, &addr_in->sin_addr.s_addr, 4); memcpy(address_ipv4->ipv4_addr, &addr_in->sin_addr.s_addr, 4);
type = DOMAIN_RULE_ADDRESS_IPV4; type = DOMAIN_RULE_ADDRESS_IPV4;
address = address_ipv4; address = (struct dns_rule *)address_ipv4;
} break; } break;
case AF_INET6: { case AF_INET6: {
struct sockaddr_in6 *addr_in6 = NULL; struct sockaddr_in6 *addr_in6 = NULL;
addr_in6 = (struct sockaddr_in6 *)&addr; addr_in6 = (struct sockaddr_in6 *)&addr;
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) { if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
address_ipv4 = malloc(sizeof(*address_ipv4)); address_ipv4 = _new_dns_rule(DOMAIN_RULE_ADDRESS_IPV4);
if (address_ipv4 == NULL) { if (address_ipv4 == NULL) {
goto errout; goto errout;
} }
memcpy(address_ipv4->ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4); memcpy(address_ipv4->ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4);
type = DOMAIN_RULE_ADDRESS_IPV4; type = DOMAIN_RULE_ADDRESS_IPV4;
address = address_ipv4; address = (struct dns_rule *)address_ipv4;
} else { } else {
address_ipv6 = malloc(sizeof(*address_ipv6)); address_ipv6 = _new_dns_rule(DOMAIN_RULE_ADDRESS_IPV6);
if (address_ipv6 == NULL) { if (address_ipv6 == NULL) {
goto errout; goto errout;
} }
memcpy(address_ipv6->ipv6_addr, addr_in6->sin6_addr.s6_addr, 16); memcpy(address_ipv6->ipv6_addr, addr_in6->sin6_addr.s6_addr, 16);
type = DOMAIN_RULE_ADDRESS_IPV6; type = DOMAIN_RULE_ADDRESS_IPV6;
address = address_ipv6; address = (struct dns_rule *)address_ipv6;
} }
} break; } break;
default: default:
@@ -816,10 +951,11 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
goto errout; goto errout;
} }
_dns_rule_put(address);
return 0; return 0;
errout: errout:
if (address) { if (address) {
free(address); _dns_rule_put(address);
} }
tlog(TLOG_ERROR, "add address %s, %s failed", domain, domain_address); tlog(TLOG_ERROR, "add address %s, %s failed", domain, domain_address);
@@ -855,7 +991,6 @@ static int _config_speed_check_mode_parser(struct dns_domain_check_orders *check
int i = 0; int i = 0;
safe_strncpy(tmpbuff, mode, DNS_MAX_OPT_LEN); safe_strncpy(tmpbuff, mode, DNS_MAX_OPT_LEN);
memset(check_orders, 0, sizeof(*check_orders));
ptr = tmpbuff; ptr = tmpbuff;
do { do {
@@ -1086,7 +1221,7 @@ static int _conf_domain_rule_nameserver(char *domain, const char *group_name)
goto errout; goto errout;
} }
nameserver_rule = malloc(sizeof(*nameserver_rule)); nameserver_rule = _new_dns_rule(DOMAIN_RULE_NAMESERVER);
if (nameserver_rule == NULL) { if (nameserver_rule == NULL) {
goto errout; goto errout;
} }
@@ -1105,10 +1240,12 @@ static int _conf_domain_rule_nameserver(char *domain, const char *group_name)
goto errout; goto errout;
} }
_dns_rule_put(&nameserver_rule->head);
return 0; return 0;
errout: errout:
if (nameserver_rule) { if (nameserver_rule) {
free(nameserver_rule); _dns_rule_put(&nameserver_rule->head);
} }
tlog(TLOG_ERROR, "add nameserver %s, %s failed", domain, group_name); tlog(TLOG_ERROR, "add nameserver %s, %s failed", domain, group_name);
@@ -1263,6 +1400,50 @@ static void _config_qtype_soa_table_destroy(void)
} }
} }
static void _config_domain_set_name_table_destroy(void)
{
struct dns_domain_set_name_list *set_name_list = NULL;
struct hlist_node *tmp = NULL;
struct dns_domain_set_name *set_name = NULL;
struct dns_domain_set_name *tmp1 = NULL;
unsigned long i = 0;
hash_for_each_safe(dns_domain_set_name_table.names, i, tmp, set_name_list, node)
{
hlist_del_init(&set_name_list->node);
list_for_each_entry_safe(set_name, tmp1, &set_name_list->set_name_list, list)
{
list_del(&set_name->list);
free(set_name);
}
free(set_name_list);
}
}
static void _config_domain_set_rule_table_destroy(void)
{
struct dns_domain_set_rule_list *set_rule_list = NULL;
struct hlist_node *tmp = NULL;
struct dns_domain_set_rule *set_rule = NULL;
struct dns_domain_set_rule *tmp1 = NULL;
unsigned long i = 0;
hash_for_each_safe(dns_domain_set_rule_table.rule_list, i, tmp, set_rule_list, node)
{
hlist_del_init(&set_rule_list->node);
list_for_each_entry_safe(set_rule, tmp1, &set_rule_list->domain_ruls_list, list)
{
list_del(&set_rule->list);
if (set_rule->rule) {
_dns_rule_put(set_rule->rule);
}
free(set_rule);
}
free(set_rule_list);
}
}
static int _config_blacklist_ip(void *data, int argc, char *argv[]) static int _config_blacklist_ip(void *data, int argc, char *argv[])
{ {
if (argc <= 1) { if (argc <= 1) {
@@ -1353,11 +1534,10 @@ static int _conf_domain_rule_speed_check(char *domain, const char *mode)
{ {
struct dns_domain_check_orders *check_orders = NULL; struct dns_domain_check_orders *check_orders = NULL;
check_orders = malloc(sizeof(*check_orders) * DOMAIN_CHECK_NUM); check_orders = _new_dns_rule(DOMAIN_RULE_CHECKSPEED);
if (check_orders == NULL) { if (check_orders == NULL) {
goto errout; goto errout;
} }
memset(check_orders, 0, sizeof(*check_orders));
if (_config_speed_check_mode_parser(check_orders, mode) != 0) { if (_config_speed_check_mode_parser(check_orders, mode) != 0) {
goto errout; goto errout;
@@ -1367,14 +1547,111 @@ static int _conf_domain_rule_speed_check(char *domain, const char *mode)
goto errout; goto errout;
} }
_dns_rule_put(&check_orders->head);
return 0; return 0;
errout: errout:
if (check_orders) { if (check_orders) {
free(check_orders); _dns_rule_put(&check_orders->head);
} }
return 0; return 0;
} }
static int _conf_domain_set(void *data, int argc, char *argv[])
{
int opt = 0;
uint32_t key = 0;
struct dns_domain_set_name *domain_set = NULL;
struct dns_domain_set_name_list *domain_set_name_list = NULL;
char set_name[DNS_MAX_CNAME_LEN] = {0};
/* clang-format off */
static struct option long_options[] = {
{"name", required_argument, NULL, 'n'},
{"type", required_argument, NULL, 't'},
{"file", required_argument, NULL, 'f'},
{NULL, 0, NULL, 0}
};
if (argc <= 1) {
tlog(TLOG_ERROR, "invalid parameter.");
goto errout;
}
domain_set = malloc(sizeof(*domain_set));
if (domain_set == NULL) {
tlog(TLOG_ERROR, "cannot malloc memory.");
goto errout;
}
memset(domain_set, 0, sizeof(*domain_set));
INIT_LIST_HEAD(&domain_set->list);
optind = 1;
while (1) {
opt = getopt_long_only(argc, argv, "n:t:f:", long_options, NULL);
if (opt == -1) {
break;
}
switch (opt) {
case 'n':
safe_strncpy(set_name, optarg, DNS_MAX_CNAME_LEN);
break;
case 't': {
const char *type = optarg;
if (strncmp(type, "list", 5) == 0) {
domain_set->type = DNS_DOMAIN_SET_LIST;
} else if (strncmp(type, "geosite", 7) == 0) {
domain_set->type = DNS_DOMAIN_SET_GEOSITE;
} else {
tlog(TLOG_ERROR, "invalid domain set type.");
goto errout;
}
break;
}
case 'f':
conf_get_conf_fullpath(optarg, domain_set->file, DNS_MAX_PATH);
break;
default:
break;
}
}
/* clang-format on */
if (set_name[0] == 0 || domain_set->file[0] == 0) {
tlog(TLOG_ERROR, "invalid parameter.");
goto errout;
}
key = hash_string(set_name);
hash_for_each_possible(dns_domain_set_name_table.names, domain_set_name_list, node, key)
{
if (strcmp(domain_set_name_list->name, set_name) == 0) {
break;
}
}
if (domain_set_name_list == NULL) {
domain_set_name_list = malloc(sizeof(*domain_set_name_list));
if (domain_set_name_list == NULL) {
tlog(TLOG_ERROR, "cannot malloc memory.");
goto errout;
}
memset(domain_set_name_list, 0, sizeof(*domain_set_name_list));
INIT_LIST_HEAD(&domain_set_name_list->set_name_list);
safe_strncpy(domain_set_name_list->name, set_name, DNS_MAX_CNAME_LEN);
hash_add(dns_domain_set_name_table.names, &domain_set_name_list->node, key);
}
list_add_tail(&domain_set->list, &domain_set_name_list->set_name_list);
return 0;
errout:
if (domain_set) {
free(domain_set);
}
return -1;
}
static int _conf_domain_rules(void *data, int argc, char *argv[]) static int _conf_domain_rules(void *data, int argc, char *argv[])
{ {
int opt = 0; int opt = 0;
@@ -1750,8 +2027,8 @@ static int _conf_dhcp_lease_dnsmasq_file(void *data, int argc, char *argv[])
return -1; return -1;
} }
safe_strncpy(dns_conf_dnsmasq_lease_file, argv[1], DNS_MAX_PATH); conf_get_conf_fullpath(argv[1], dns_conf_dnsmasq_lease_file, sizeof(dns_conf_dnsmasq_lease_file));
if (_conf_dhcp_lease_dnsmasq_add(argv[1]) != 0) { if (_conf_dhcp_lease_dnsmasq_add(dns_conf_dnsmasq_lease_file) != 0) {
return -1; return -1;
} }
@@ -1920,12 +2197,14 @@ static struct config_item _config_item[] = {
CONF_CUSTOM("ignore-ip", _conf_ip_ignore, NULL), CONF_CUSTOM("ignore-ip", _conf_ip_ignore, NULL),
CONF_CUSTOM("edns-client-subnet", _conf_edns_client_subnet, NULL), CONF_CUSTOM("edns-client-subnet", _conf_edns_client_subnet, NULL),
CONF_CUSTOM("domain-rules", _conf_domain_rules, NULL), CONF_CUSTOM("domain-rules", _conf_domain_rules, NULL),
CONF_CUSTOM("domain-set", _conf_domain_set, NULL),
CONF_CUSTOM("dnsmasq-lease-file", _conf_dhcp_lease_dnsmasq_file, NULL), CONF_CUSTOM("dnsmasq-lease-file", _conf_dhcp_lease_dnsmasq_file, NULL),
CONF_CUSTOM("hosts-file", _conf_hosts_file, NULL), CONF_CUSTOM("hosts-file", _conf_hosts_file, NULL),
CONF_STRING("ca-file", (char *)&dns_conf_ca_file, DNS_MAX_PATH), CONF_STRING("ca-file", (char *)&dns_conf_ca_file, DNS_MAX_PATH),
CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH), CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH),
CONF_STRING("user", (char *)&dns_conf_user, sizeof(dns_conf_user)), CONF_STRING("user", (char *)&dns_conf_user, sizeof(dns_conf_user)),
CONF_YESNO("debug-save-fail-packet", &dns_save_fail_packet), CONF_YESNO("debug-save-fail-packet", &dns_save_fail_packet),
CONF_STRING("resolv-file", (char *)&dns_resolv_file, sizeof(dns_resolv_file)),
CONF_STRING("debug-save-fail-packet-dir", (char *)&dns_save_fail_packet_dir, sizeof(dns_save_fail_packet_dir)), CONF_STRING("debug-save-fail-packet-dir", (char *)&dns_save_fail_packet_dir, sizeof(dns_save_fail_packet_dir)),
CONF_CUSTOM("conf-file", config_addtional_file, NULL), CONF_CUSTOM("conf-file", config_addtional_file, NULL),
CONF_END(), CONF_END(),
@@ -1984,6 +2263,96 @@ int config_addtional_file(void *data, int argc, char *argv[])
return load_conf(file_path, _config_item, _conf_printf); return load_conf(file_path, _config_item, _conf_printf);
} }
static int _update_domain_set_from_list(const char *file, struct dns_domain_set_rule_list *set_rule_list)
{
FILE *fp = NULL;
char line[MAX_LINE_LEN];
char domain[DNS_MAX_CNAME_LEN];
int ret = 0;
int line_no = 0;
int filed_num = 0;
struct dns_domain_set_rule *set_rule = NULL;
fp = fopen(file, "r");
if (fp == NULL) {
tlog(TLOG_WARN, "open file %s error, %s", file, strerror(errno));
return 0;
}
line_no = 0;
while (fgets(line, MAX_LINE_LEN, fp)) {
line_no++;
filed_num = sscanf(line, "%256s", domain);
if (filed_num <= 0) {
continue;
}
if (domain[0] == '#' || domain[0] == '\n') {
continue;
}
list_for_each_entry(set_rule, &set_rule_list->domain_ruls_list, list)
{
if (set_rule->type == DOMAIN_RULE_FLAGS) {
ret = _config_domain_rule_flag_set(domain, set_rule->flags, set_rule->is_clear_flag);
} else {
ret = _config_domain_rule_add(domain, set_rule->type, set_rule->rule);
}
if (ret != 0) {
tlog(TLOG_WARN, "process file %s failed at line %d.", file, line_no);
continue;
}
}
}
fclose(fp);
return ret;
}
static int _update_domain_set(void)
{
struct dns_domain_set_rule_list *set_rule_list = NULL;
struct dns_domain_set_name_list *set_name_list = NULL;
struct dns_domain_set_name *set_name_item = NULL;
unsigned long i = 0;
uint32_t key = 0;
hash_for_each(dns_domain_set_rule_table.rule_list, i, set_rule_list, node)
{
key = hash_string(set_rule_list->domain_set);
hash_for_each_possible(dns_domain_set_name_table.names, set_name_list, node, key)
{
if (strcmp(set_name_list->name, set_rule_list->domain_set) == 0) {
break;
}
}
if (set_name_list == NULL) {
tlog(TLOG_WARN, "domain set %s not found.", set_rule_list->domain_set);
continue;
}
list_for_each_entry(set_name_item, &set_name_list->set_name_list, list)
{
switch (set_name_item->type) {
case DNS_DOMAIN_SET_LIST:
_update_domain_set_from_list(set_name_item->file, set_rule_list);
break;
case DNS_DOMAIN_SET_GEOSITE:
break;
default:
tlog(TLOG_WARN, "domain set %s type %d not support.", set_name_list->name, set_name_item->type);
break;
}
}
}
return 0;
}
static int _dns_server_load_conf_init(void) static int _dns_server_load_conf_init(void)
{ {
dns_conf_address_rule.ipv4 = New_Radix(); dns_conf_address_rule.ipv4 = New_Radix();
@@ -2000,6 +2369,8 @@ static int _dns_server_load_conf_init(void)
hash_init(dns_group_table.group); hash_init(dns_group_table.group);
hash_init(dns_hosts_table.hosts); hash_init(dns_hosts_table.hosts);
hash_init(dns_ptr_table.ptr); hash_init(dns_ptr_table.ptr);
hash_init(dns_domain_set_rule_table.rule_list);
hash_init(dns_domain_set_name_table.names);
_config_setup_smartdns_domain(); _config_setup_smartdns_domain();
@@ -2093,10 +2464,26 @@ static int _dns_conf_load_post(void)
dns_conf_response_mode_enum[dns_conf_response_mode].name); dns_conf_response_mode_enum[dns_conf_response_mode].name);
} }
if ((dns_conf_rr_ttl_min > dns_conf_rr_ttl_max) && dns_conf_rr_ttl_max > 0) {
dns_conf_rr_ttl_min = dns_conf_rr_ttl_max;
}
if ((dns_conf_rr_ttl_max < dns_conf_rr_ttl_min) && dns_conf_rr_ttl_max > 0) {
dns_conf_rr_ttl_max = dns_conf_rr_ttl_min;
}
if (dns_conf_local_ttl == 0) { if (dns_conf_local_ttl == 0) {
dns_conf_local_ttl = dns_conf_rr_ttl_min; dns_conf_local_ttl = dns_conf_rr_ttl_min;
} }
if (dns_resolv_file[0] == '\0') {
safe_strncpy(dns_resolv_file, DNS_RESOLV_FILE, sizeof(dns_resolv_file));
}
_update_domain_set();
_config_domain_set_name_table_destroy();
_config_domain_set_rule_table_destroy();
return 0; return 0;
} }

View File

@@ -20,6 +20,7 @@
#define _DNS_CONF #define _DNS_CONF
#include "art.h" #include "art.h"
#include "atomic.h"
#include "conf.h" #include "conf.h"
#include "dns.h" #include "dns.h"
#include "dns_client.h" #include "dns_client.h"
@@ -102,16 +103,25 @@ typedef enum {
#define BIND_FLAG_NO_DUALSTACK_SELECTION (1 << 7) #define BIND_FLAG_NO_DUALSTACK_SELECTION (1 << 7)
#define BIND_FLAG_FORCE_AAAA_SOA (1 << 8) #define BIND_FLAG_FORCE_AAAA_SOA (1 << 8)
struct dns_rule {
atomic_t refcnt;
enum domain_rule rule;
char rule_data[];
};
struct dns_rule_flags { struct dns_rule_flags {
struct dns_rule head;
unsigned int flags; unsigned int flags;
unsigned int is_flag_set; unsigned int is_flag_set;
}; };
struct dns_address_IPV4 { struct dns_rule_address_IPV4 {
struct dns_rule head;
unsigned char ipv4_addr[DNS_RR_A_LEN]; unsigned char ipv4_addr[DNS_RR_A_LEN];
}; };
struct dns_address_IPV6 { struct dns_rule_address_IPV6 {
struct dns_rule head;
unsigned char ipv6_addr[DNS_RR_AAAA_LEN]; unsigned char ipv6_addr[DNS_RR_AAAA_LEN];
}; };
@@ -121,14 +131,17 @@ struct dns_ipset_name {
}; };
struct dns_ipset_rule { struct dns_ipset_rule {
struct dns_rule head;
const char *ipsetname; const char *ipsetname;
}; };
struct dns_domain_rule { struct dns_domain_rule {
void *rules[DOMAIN_RULE_MAX]; struct dns_rule head;
struct dns_rule *rules[DOMAIN_RULE_MAX];
}; };
struct dns_nameserver_rule { struct dns_nameserver_rule {
struct dns_rule head;
const char *group_name; const char *group_name;
}; };
@@ -145,6 +158,7 @@ struct dns_domain_check_order {
}; };
struct dns_domain_check_orders { struct dns_domain_check_orders {
struct dns_rule head;
struct dns_domain_check_order orders[DOMAIN_CHECK_NUM]; struct dns_domain_check_order orders[DOMAIN_CHECK_NUM];
}; };
@@ -255,6 +269,46 @@ struct dns_qtype_soa_table {
}; };
extern struct dns_qtype_soa_table dns_qtype_soa_table; extern struct dns_qtype_soa_table dns_qtype_soa_table;
struct dns_domain_set_rule {
struct list_head list;
enum domain_rule type;
void *rule;
unsigned int flags;
unsigned int is_clear_flag;
};
struct dns_domain_set_rule_list {
struct hlist_node node;
char domain_set[DNS_MAX_CNAME_LEN];
struct list_head domain_ruls_list;
};
struct dns_domain_set_rule_table {
DECLARE_HASHTABLE(rule_list, 4);
};
extern struct dns_domain_set_rule_table dns_domain_set_rule_table;
enum dns_domain_set_type {
DNS_DOMAIN_SET_LIST = 0,
DNS_DOMAIN_SET_GEOSITE = 1,
};
struct dns_domain_set_name {
struct list_head list;
enum dns_domain_set_type type;
char file[DNS_MAX_PATH];
};
struct dns_domain_set_name_list {
struct hlist_node node;
char name[DNS_MAX_CNAME_LEN];
struct list_head set_name_list;
};
struct dns_domain_set_name_table {
DECLARE_HASHTABLE(names, 4);
};
extern struct dns_domain_set_name_table dns_domain_set_name_table;
extern struct dns_bind_ip dns_conf_bind_ip[DNS_MAX_BIND_IP]; extern struct dns_bind_ip dns_conf_bind_ip[DNS_MAX_BIND_IP];
extern int dns_conf_bind_ip_num; extern int dns_conf_bind_ip_num;
@@ -325,6 +379,7 @@ extern char dns_conf_sni_proxy_ip[DNS_MAX_IPLEN];
extern int dns_save_fail_packet; extern int dns_save_fail_packet;
extern char dns_save_fail_packet_dir[DNS_MAX_PATH]; extern char dns_save_fail_packet_dir[DNS_MAX_PATH];
extern char dns_resolv_file[DNS_MAX_PATH];
void dns_server_load_exit(void); void dns_server_load_exit(void);

View File

@@ -316,6 +316,15 @@ static int _dns_server_epoll_ctl(struct dns_server_conn_head *head, int op, uint
return 0; return 0;
} }
static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_rule rule)
{
if (rule >= DOMAIN_RULE_MAX || request == NULL) {
return NULL;
}
return request->domain_rule.rules[rule];
}
static void _dns_server_set_dualstack_selection(struct dns_request *request) static void _dns_server_set_dualstack_selection(struct dns_request *request)
{ {
struct dns_rule_flags *rule_flag = NULL; struct dns_rule_flags *rule_flag = NULL;
@@ -325,7 +334,7 @@ static void _dns_server_set_dualstack_selection(struct dns_request *request)
return; return;
} }
rule_flag = request->domain_rule.rules[DOMAIN_RULE_FLAGS]; rule_flag = _dns_server_get_dns_rule(request, DOMAIN_RULE_FLAGS);
if (rule_flag) { if (rule_flag) {
if (rule_flag->flags & DOMAIN_FLAG_DUALSTACK_SELECT) { if (rule_flag->flags & DOMAIN_FLAG_DUALSTACK_SELECT) {
request->dualstack_selection = 1; request->dualstack_selection = 1;
@@ -361,7 +370,7 @@ static int _dns_server_is_return_soa(struct dns_request *request)
} }
} }
rule_flag = request->domain_rule.rules[DOMAIN_RULE_FLAGS]; rule_flag = _dns_server_get_dns_rule(request, DOMAIN_RULE_FLAGS);
if (rule_flag) { if (rule_flag) {
flags = rule_flag->flags; flags = rule_flag->flags;
if (flags & DOMAIN_FLAG_ADDR_SOA) { if (flags & DOMAIN_FLAG_ADDR_SOA) {
@@ -733,11 +742,11 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
} }
/* add SOA record */ /* add SOA record */
if (has_soa) { if (has_soa) {
ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa); ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, request->ip_ttl, &request->soa);
tlog(TLOG_DEBUG, "result: %s, qtype: %d, return SOA", request->domain, context->qtype); tlog(TLOG_DEBUG, "result: %s, qtype: %d, return SOA", request->domain, context->qtype);
} else if (context->do_force_soa == 1) { } else if (context->do_force_soa == 1) {
_dns_server_setup_soa(request); _dns_server_setup_soa(request);
ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa); ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, request->ip_ttl, &request->soa);
} }
if (request->has_ecs) { if (request->has_ecs) {
@@ -793,7 +802,7 @@ static int _dns_setup_dns_raw_packet(struct dns_server_post_context *context)
/* encode to binary data */ /* encode to binary data */
int encode_len = dns_encode(context->inpacket, context->inpacket_maxlen, context->packet); int encode_len = dns_encode(context->inpacket, context->inpacket_maxlen, context->packet);
if (encode_len <= 0) { if (encode_len <= 0) {
tlog(TLOG_ERROR, "encode raw packet failed for %s", context->request->domain); tlog(TLOG_DEBUG, "encode raw packet failed for %s", context->request->domain);
return -1; return -1;
} }
@@ -1317,15 +1326,15 @@ static int _dns_server_setup_ipset_packet(struct dns_server_post_context *contex
} }
/* check ipset rule */ /* check ipset rule */
rule_flags = request->domain_rule.rules[DOMAIN_RULE_FLAGS]; rule_flags = _dns_server_get_dns_rule(request, DOMAIN_RULE_FLAGS);
if (!rule_flags || (rule_flags->flags & DOMAIN_FLAG_IPSET_IGN) == 0) { if (!rule_flags || (rule_flags->flags & DOMAIN_FLAG_IPSET_IGN) == 0) {
ipset_rule = request->domain_rule.rules[DOMAIN_RULE_IPSET]; ipset_rule = _dns_server_get_dns_rule(request, DOMAIN_RULE_IPSET);
} }
if (!rule_flags || (rule_flags->flags & DOMAIN_FLAG_IPSET_IPV4_IGN) == 0) { if (!rule_flags || (rule_flags->flags & DOMAIN_FLAG_IPSET_IPV4_IGN) == 0) {
ipset_rule_v4 = request->domain_rule.rules[DOMAIN_RULE_IPSET_IPV4]; ipset_rule_v4 = _dns_server_get_dns_rule(request, DOMAIN_RULE_IPSET_IPV4);
} }
if (!rule_flags || (rule_flags->flags & DOMAIN_FLAG_IPSET_IPV6_IGN) == 0) { if (!rule_flags || (rule_flags->flags & DOMAIN_FLAG_IPSET_IPV6_IGN) == 0) {
ipset_rule_v6 = request->domain_rule.rules[DOMAIN_RULE_IPSET_IPV6]; ipset_rule_v6 = _dns_server_get_dns_rule(request, DOMAIN_RULE_IPSET_IPV6);
} }
if (!(ipset_rule || ipset_rule_v4 || ipset_rule_v6)) { if (!(ipset_rule || ipset_rule_v4 || ipset_rule_v6)) {
@@ -1566,6 +1575,7 @@ static int _dns_server_force_dualstack(struct dns_request *request)
static int _dns_server_request_complete(struct dns_request *request) static int _dns_server_request_complete(struct dns_request *request)
{ {
int ttl = DNS_SERVER_TMOUT_TTL; int ttl = DNS_SERVER_TMOUT_TTL;
int reply_ttl = ttl;
if (request->rcode == DNS_RC_SERVFAIL || request->rcode == DNS_RC_NXDOMAIN) { if (request->rcode == DNS_RC_SERVFAIL || request->rcode == DNS_RC_NXDOMAIN) {
ttl = DNS_SERVER_FAIL_TTL; ttl = DNS_SERVER_FAIL_TTL;
@@ -1617,6 +1627,15 @@ out:
} }
} }
reply_ttl = ttl;
if (request->passthrough == 0 && dns_conf_cachesize > 0 &&
request->check_order_list->orders[0].type != DOMAIN_CHECK_NONE) {
reply_ttl = dns_conf_serve_expired_reply_ttl;
if (reply_ttl < 2) {
reply_ttl = 2;
}
}
struct dns_server_post_context context; struct dns_server_post_context context;
_dns_server_post_context_init(&context, request); _dns_server_post_context_init(&context, request);
context.do_cache = 1; context.do_cache = 1;
@@ -1624,7 +1643,7 @@ out:
context.do_force_soa = request->dualstack_selection_force_soa; context.do_force_soa = request->dualstack_selection_force_soa;
context.do_audit = 1; context.do_audit = 1;
context.do_reply = 1; context.do_reply = 1;
context.reply_ttl = ttl; context.reply_ttl = reply_ttl;
context.skip_notify_count = 1; context.skip_notify_count = 1;
_dns_request_post(&context); _dns_request_post(&context);
@@ -1814,6 +1833,10 @@ static void _dns_server_complete_with_multi_ipaddress(struct dns_request *reques
_dns_server_force_dualstack(request); _dns_server_force_dualstack(request);
} }
if (request->passthrough && do_reply == 0) {
return;
}
_dns_server_post_context_init(&context, request); _dns_server_post_context_init(&context, request);
context.do_cache = 1; context.do_cache = 1;
context.do_ipset = 1; context.do_ipset = 1;
@@ -2312,6 +2335,7 @@ static int _dns_server_process_answer_A(struct dns_rrs *rrs, struct dns_request
if (addr[0] == 0 || addr[0] == 127) { if (addr[0] == 0 || addr[0] == 127) {
/* If half of the servers return the same result, then ignore this address */ /* If half of the servers return the same result, then ignore this address */
if (atomic_inc_return(&request->adblock) <= (dns_server_num() / 2 + dns_server_num() % 2)) { if (atomic_inc_return(&request->adblock) <= (dns_server_num() / 2 + dns_server_num() % 2)) {
request->rcode = DNS_RC_NOERROR;
_dns_server_request_release(request); _dns_server_request_release(request);
return -1; return -1;
} }
@@ -2388,6 +2412,7 @@ static int _dns_server_process_answer_AAAA(struct dns_rrs *rrs, struct dns_reque
if (_dns_server_is_adblock_ipv6(addr) == 0) { if (_dns_server_is_adblock_ipv6(addr) == 0) {
/* If half of the servers return the same result, then ignore this address */ /* If half of the servers return the same result, then ignore this address */
if (atomic_inc_return(&request->adblock) <= (dns_server_num() / 2 + dns_server_num() % 2)) { if (atomic_inc_return(&request->adblock) <= (dns_server_num() / 2 + dns_server_num() % 2)) {
request->rcode = DNS_RC_NOERROR;
_dns_server_request_release(request); _dns_server_request_release(request);
return -1; return -1;
} }
@@ -2485,6 +2510,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum); request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
int soa_num = atomic_inc_return(&request->soa_num); int soa_num = atomic_inc_return(&request->soa_num);
if ((soa_num >= (dns_server_num() / 3) + 1 || soa_num > 4) && atomic_read(&request->ip_map_num) <= 0) { if ((soa_num >= (dns_server_num() / 3) + 1 || soa_num > 4) && atomic_read(&request->ip_map_num) <= 0) {
request->ip_ttl = ttl;
_dns_server_request_complete(request); _dns_server_request_complete(request);
} }
} break; } break;
@@ -3023,7 +3049,7 @@ static int _dns_server_reply_request_eth_ip(struct dns_request *request)
} }
request->rcode = DNS_RC_NOERROR; request->rcode = DNS_RC_NOERROR;
request->ip_ttl = 600; request->ip_ttl = dns_conf_local_ttl;
request->has_ip = 1; request->has_ip = 1;
struct dns_server_post_context context; struct dns_server_post_context context;
@@ -3324,7 +3350,7 @@ static int _dns_server_pre_process_rule_flags(struct dns_request *request)
unsigned int flags = 0; unsigned int flags = 0;
/* get domain rule flag */ /* get domain rule flag */
rule_flag = request->domain_rule.rules[DOMAIN_RULE_FLAGS]; rule_flag = _dns_server_get_dns_rule(request, DOMAIN_RULE_FLAGS);
if (rule_flag == NULL) { if (rule_flag == NULL) {
goto out; goto out;
} }
@@ -3378,14 +3404,15 @@ out:
soa: soa:
/* return SOA */ /* return SOA */
request->ip_ttl = 30;
_dns_server_reply_SOA(DNS_RC_NOERROR, request); _dns_server_reply_SOA(DNS_RC_NOERROR, request);
return 0; return 0;
} }
static int _dns_server_process_address(struct dns_request *request) static int _dns_server_process_address(struct dns_request *request)
{ {
struct dns_address_IPV4 *address_ipv4 = NULL; struct dns_rule_address_IPV4 *address_ipv4 = NULL;
struct dns_address_IPV6 *address_ipv6 = NULL; struct dns_rule_address_IPV6 *address_ipv6 = NULL;
if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_RULE_ADDR) == 0) { if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_RULE_ADDR) == 0) {
goto errout; goto errout;
@@ -3397,14 +3424,14 @@ static int _dns_server_process_address(struct dns_request *request)
if (request->domain_rule.rules[DOMAIN_RULE_ADDRESS_IPV4] == NULL) { if (request->domain_rule.rules[DOMAIN_RULE_ADDRESS_IPV4] == NULL) {
goto errout; goto errout;
} }
address_ipv4 = request->domain_rule.rules[DOMAIN_RULE_ADDRESS_IPV4]; address_ipv4 = _dns_server_get_dns_rule(request, DOMAIN_RULE_ADDRESS_IPV4);
memcpy(request->ip_addr, address_ipv4->ipv4_addr, DNS_RR_A_LEN); memcpy(request->ip_addr, address_ipv4->ipv4_addr, DNS_RR_A_LEN);
break; break;
case DNS_T_AAAA: case DNS_T_AAAA:
if (request->domain_rule.rules[DOMAIN_RULE_ADDRESS_IPV6] == NULL) { if (request->domain_rule.rules[DOMAIN_RULE_ADDRESS_IPV6] == NULL) {
goto errout; goto errout;
} }
address_ipv6 = request->domain_rule.rules[DOMAIN_RULE_ADDRESS_IPV6]; address_ipv6 = _dns_server_get_dns_rule(request, DOMAIN_RULE_ADDRESS_IPV6);
memcpy(request->ip_addr, address_ipv6->ipv6_addr, DNS_RR_AAAA_LEN); memcpy(request->ip_addr, address_ipv6->ipv6_addr, DNS_RR_AAAA_LEN);
break; break;
default: default:
@@ -3452,7 +3479,7 @@ static void _dns_server_process_speed_check_rule(struct dns_request *request)
struct dns_domain_check_orders *check_order = NULL; struct dns_domain_check_orders *check_order = NULL;
/* get domain rule flag */ /* get domain rule flag */
check_order = request->domain_rule.rules[DOMAIN_RULE_CHECKSPEED]; check_order = _dns_server_get_dns_rule(request, DOMAIN_RULE_CHECKSPEED);
if (check_order == NULL) { if (check_order == NULL) {
return; return;
} }
@@ -3796,7 +3823,7 @@ static int _dns_server_process_smartdns_domain(struct dns_request *request)
unsigned int flags = 0; unsigned int flags = 0;
/* get domain rule flag */ /* get domain rule flag */
rule_flag = request->domain_rule.rules[DOMAIN_RULE_FLAGS]; rule_flag = _dns_server_get_dns_rule(request, DOMAIN_RULE_FLAGS);
if (rule_flag == NULL) { if (rule_flag == NULL) {
return -1; return -1;
} }
@@ -3813,10 +3840,6 @@ static int _dns_server_process_special_query(struct dns_request *request)
{ {
int ret = 0; int ret = 0;
if (_dns_server_process_smartdns_domain(request) == 0) {
goto clean_exit;
}
switch (request->qtype) { switch (request->qtype) {
case DNS_T_PTR: case DNS_T_PTR:
/* return PTR record */ /* return PTR record */
@@ -3858,7 +3881,7 @@ static const char *_dns_server_get_request_groupname(struct dns_request *request
/* Get the nameserver rule */ /* Get the nameserver rule */
if (request->domain_rule.rules[DOMAIN_RULE_NAMESERVER]) { if (request->domain_rule.rules[DOMAIN_RULE_NAMESERVER]) {
struct dns_nameserver_rule *nameserver_rule = request->domain_rule.rules[DOMAIN_RULE_NAMESERVER]; struct dns_nameserver_rule *nameserver_rule = _dns_server_get_dns_rule(request, DOMAIN_RULE_NAMESERVER);
return nameserver_rule->group_name; return nameserver_rule->group_name;
} }
@@ -4040,7 +4063,6 @@ static int _dns_server_do_query(struct dns_request *request)
safe_strncpy(request->dns_group_name, group_name, DNS_GROUP_NAME_LEN); safe_strncpy(request->dns_group_name, group_name, DNS_GROUP_NAME_LEN);
} }
_dns_server_set_dualstack_selection(request); _dns_server_set_dualstack_selection(request);
if (_dns_server_process_special_query(request) == 0) { if (_dns_server_process_special_query(request) == 0) {
@@ -4057,6 +4079,10 @@ static int _dns_server_do_query(struct dns_request *request)
goto clean_exit; goto clean_exit;
} }
if (_dns_server_process_smartdns_domain(request) == 0) {
goto clean_exit;
}
if (_dns_server_process_host(request) == 0) { if (_dns_server_process_host(request) == 0) {
goto clean_exit; goto clean_exit;
} }

View File

@@ -1112,10 +1112,6 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
tlog(TLOG_DEBUG, "ping %s, id = %d", host, ping_host->sid); tlog(TLOG_DEBUG, "ping %s, id = %d", host, ping_host->sid);
addrkey = _fast_ping_hash_key(ping_host->sid, &ping_host->addr); addrkey = _fast_ping_hash_key(ping_host->sid, &ping_host->addr);
pthread_mutex_lock(&ping.map_lock);
_fast_ping_host_get(ping_host);
hash_add(ping.addrmap, &ping_host->addr_node, addrkey);
pthread_mutex_unlock(&ping.map_lock);
_fast_ping_host_get(ping_host); _fast_ping_host_get(ping_host);
_fast_ping_host_get(ping_host); _fast_ping_host_get(ping_host);
@@ -1124,7 +1120,11 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
goto errout_remove; goto errout_remove;
} }
pthread_mutex_lock(&ping.map_lock);
_fast_ping_host_get(ping_host);
hash_add(ping.addrmap, &ping_host->addr_node, addrkey);
ping_host->run = 1; ping_host->run = 1;
pthread_mutex_unlock(&ping.map_lock);
freeaddrinfo(gai); freeaddrinfo(gai);
_fast_ping_host_put(ping_host); _fast_ping_host_put(ping_host);
return ping_host; return ping_host;

View File

@@ -160,4 +160,6 @@ void load_exit(void);
const char *conf_get_conf_file(void); const char *conf_get_conf_file(void);
const char *conf_get_conf_fullpath(const char *path, char *fullpath, size_t path_len);
#endif // !_GENERIC_CONF_H #endif // !_GENERIC_CONF_H

View File

@@ -18,16 +18,46 @@
#include "conf.h" #include "conf.h"
#include <getopt.h> #include <getopt.h>
#include <libgen.h>
#include <linux/limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
static const char *currrent_conf_file = NULL; static const char *current_conf_file = NULL;
const char *conf_get_conf_file(void) const char *conf_get_conf_file(void)
{ {
return currrent_conf_file; return current_conf_file;
}
const char *conf_get_conf_fullpath(const char *path, char *fullpath, size_t path_len)
{
char file_path_dir[PATH_MAX];
if (path_len < 1) {
return NULL;
}
if (path[0] == '/') {
strncpy(fullpath, path, path_len);
return fullpath;
}
strncpy(file_path_dir, conf_get_conf_file(), PATH_MAX - 1);
file_path_dir[PATH_MAX - 1] = 0;
dirname(file_path_dir);
if (file_path_dir[0] == '\0') {
strncpy(fullpath, path, path_len);
return fullpath;
}
if (snprintf(fullpath, PATH_MAX, "%s/%s", file_path_dir, path) < 0) {
return NULL;
}
return fullpath;
} }
int conf_custom(const char *item, void *data, int argc, char *argv[]) int conf_custom(const char *item, void *data, int argc, char *argv[])
@@ -303,7 +333,7 @@ static int load_conf_file(const char *file, struct config_item *items, conf_erro
conf_getopt_reset(); conf_getopt_reset();
/* call item function */ /* call item function */
currrent_conf_file = file; current_conf_file = file;
call_ret = items[i].item_func(items[i].item, items[i].data, argc, argv); call_ret = items[i].item_func(items[i].item, items[i].data, argc, argv);
ret = handler(file, line_no, call_ret); ret = handler(file, line_no, call_ret);
if (ret != 0) { if (ret != 0) {

View File

@@ -44,7 +44,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <ucontext.h> #include <ucontext.h>
#define RESOLVE_FILE "/etc/resolv.conf"
#define MAX_LINE_LEN 1024 #define MAX_LINE_LEN 1024
#define MAX_KEY_LEN 64 #define MAX_KEY_LEN 64
#define SMARTDNS_PID_FILE "/var/run/smartdns.pid" #define SMARTDNS_PID_FILE "/var/run/smartdns.pid"
@@ -82,6 +81,11 @@ static int get_uid_gid(int *uid, int *gid)
goto out; goto out;
} }
if (result == NULL) {
ret = -1;
goto out;
}
*uid = result->pw_uid; *uid = result->pw_uid;
*gid = result->pw_gid; *gid = result->pw_gid;
@@ -97,7 +101,11 @@ static int drop_root_privilege(void)
{ {
struct __user_cap_data_struct cap; struct __user_cap_data_struct cap;
struct __user_cap_header_struct header; struct __user_cap_header_struct header;
#ifdef _LINUX_CAPABILITY_VERSION_3
header.version = _LINUX_CAPABILITY_VERSION_3;
#else
header.version = _LINUX_CAPABILITY_VERSION; header.version = _LINUX_CAPABILITY_VERSION;
#endif
header.pid = 0; header.pid = 0;
int uid = 0; int uid = 0;
int gid = 0; int gid = 0;
@@ -173,9 +181,9 @@ static int _smartdns_load_from_resolv(void)
int filed_num = 0; int filed_num = 0;
int line_num = 0; int line_num = 0;
fp = fopen(RESOLVE_FILE, "r"); fp = fopen(dns_resolv_file, "r");
if (fp == NULL) { if (fp == NULL) {
tlog(TLOG_ERROR, "open %s failed, %s", RESOLVE_FILE, strerror(errno)); tlog(TLOG_ERROR, "open %s failed, %s", dns_resolv_file, strerror(errno));
return -1; return -1;
} }
@@ -496,7 +504,7 @@ static int _smartdns_create_logdir(void)
return -1; return -1;
} }
chown(logdir, uid, gid); unused = chown(logdir, uid, gid);
return 0; return 0;
} }