Compare commits

..

32 Commits

Author SHA1 Message Date
Nick Peng
60a3719ec7 dns_server: fix local ttl issue 2023-03-04 11:21:48 +08:00
Nick Peng
e897788098 readme: update readme 2023-03-03 21:31:11 +08:00
Nick Peng
1ef9da847d dns-server: fix cname rule issue 2023-03-03 21:09:27 +08:00
Nick Peng
66b86e1a8b dns-server: fix cname & dualstack issue 2023-03-02 23:20:25 +08:00
Nick Peng
95f843dc43 dns-server: fix rr-ttl-* priority issue 2023-03-01 19:53:22 +08:00
Nick Peng
6827554def dns-server: fix dns64 issue & cname dns-group-issue 2023-02-28 23:40:05 +08:00
Nick Peng
e8eddabc85 dns_client: force close server failure after 60s. 2023-02-27 00:09:33 +08:00
Nick Peng
15636c355a fast-ping: fix fast-ping issue 2023-02-26 22:59:57 +08:00
Nick Peng
b473b9c6e1 ReadMe: update some typo 2023-02-24 19:52:38 +08:00
Nick Peng
2ca4c92c9f dns-client: allow same upstream server with different proxy. 2023-02-22 21:55:07 +08:00
Nick Peng
e3271b07c4 tlog: update tlog 2023-02-22 21:54:16 +08:00
Nick Peng
c5ca3ccf43 luci: add dns64 option 2023-02-21 23:28:17 +08:00
Nick Peng
a6cb6061ec optware: fix optware init script issue 2023-02-21 22:59:50 +08:00
Nick Peng
995d5dce95 dns-client: fix tcp connect timeout issue. 2023-02-21 22:38:55 +08:00
Nick Peng
c21be04632 dns_server: update ttl issue for domain-rule 2023-02-18 21:10:44 +08:00
Nick Peng
d2d7dac7e9 dns_server: fix ttl issue. 2023-02-17 22:39:23 +08:00
Nick Peng
a62d716b10 smartdns: fix valgrind warnings. 2023-02-17 22:09:38 +08:00
Nick Peng
694d093fc4 smartdns: fix compile warnings for gcc 11. 2023-02-17 21:51:17 +08:00
Nick Peng
464bf28601 ReadMe: update rust version smartdns link 2023-02-17 21:06:40 +08:00
Nick Peng
24e1dac854 feature: Simple add dns64 support. 2023-02-17 20:51:48 +08:00
Nick Peng
e51580ea57 luci: move auto set dnsmasq option to basic settings 2023-02-16 23:09:37 +08:00
Nick Peng
499ab1b64f feature: support set ttl, ttl-min, ttl-max to domain. 2023-02-14 22:46:15 +08:00
Nick Peng
db56472b84 luci: add ipset-no-speed and nftset-no-speed options. 2023-02-12 23:02:13 +08:00
Nick Peng
60e3a109e4 dns_client: fix bootstrap DNS soa host issue. 2023-02-12 16:00:19 +08:00
Nick Peng
7256f5af32 cname: fix cname recursive query issue 2023-02-12 12:29:21 +08:00
Nick Peng
1e6a5f3809 luci: simple fix server option URI parse issue 2023-02-11 23:26:48 +08:00
Nick Peng
4941594182 dns_client: bootstrap dns: fail when domain not found. 2023-02-11 15:15:06 +08:00
Nick Peng
a6d6781a2a feature: add cname option 2023-02-11 14:34:23 +08:00
Nick Peng
be71e085ad dns_conf: fix relative path issue 2023-02-09 21:37:35 +08:00
Nick Peng
69a2f3bb7f feature: add new option: ipset-no-speed and nftset-no-speed 2023-02-09 21:31:02 +08:00
Nick Peng
d6f9b07f1c dns_client: use RAND_bytes instead getrandom for compatibility 2023-02-03 22:34:57 +08:00
Nick Peng
03ba24480b smartdns: support multiline config option and fix timer issue. 2023-02-02 20:23:53 +08:00
25 changed files with 1621 additions and 285 deletions

View File

@@ -112,7 +112,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
支持域名后缀匹配模式,简化过滤配置,过滤 20 万条记录时间 < 1ms。
1. **域名分流**
支持域名分流,不同类型的域名向不同的 DNS 服务器查询支持iptable和nftable更好的分流。
支持域名分流,不同类型的域名向不同的 DNS 服务器查询支持iptable和nftable更好的分流支持测速失败的情况下设置域名结果到对应ipset和nftset集合
1. **Windows / Linux 多平台支持**
支持标准 Linux 系统树莓派、OpenWrt 系统各种固件和华硕路由器原生固件。同时还支持 WSLWindows Subsystem for Linux适用于 Linux 的 Windows 子系统)。
@@ -120,10 +120,13 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
1. **支持 IPv4、IPv6 双栈**
支持 IPv4 和 IPV 6网络支持查询 A 和 AAAA 记录,支持双栈 IP 速度优化,并支持完全禁用 IPv6 AAAA 解析。
1. **支持DNS64**
支持DNS64转换。
1. **高性能、占用资源少**
多线程异步 IO 模式cache 缓存查询结果。
1. **主流系统官方支持**
1. **主流系统官方支持**
主流路由系统官方软件源安装smartdns。
## 架构
@@ -169,8 +172,10 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
| OpenWrtARM | smartdns.1.yyyy.MM.dd-REL.arm-openwrt-all.ipk | ARM 小端架构的 OpenWrt 系统 |
| OpenWrt LuCI | luci-app-smartdns.1.yyyy.MM.dd-REL.all.ipk | OpenWrt 管理界面 |
| OpenWrt LuCI | luci-app-smartdns.1.yyyy.MM.dd-REL.all-luci-compat-all.ipk | OpenWrt 管理界面、OpenWrt 18.xx 及之前版本 |
| Windows | smartdns-rs https://github.com/mokeyish/smartdns-rs | Rust版本SmartDNS | [Rust版本SmartDNS](https://github.com/mokeyish/smartdns-rs) |
| MacOS | smartdns-rs https://github.com/mokeyish/smartdns-rs | Rust版本SmartDNS |
**[前往 Release 页面下载](https://github.com/pymumu/smartdns/releases)。**
**[前往 Release 页面下载](https://github.com/pymumu/smartdns/releases)。**
**请注意:**
@@ -602,13 +607,17 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
| speed-check-mode | 测速模式选择 | 无 | [ping\|tcp:[80]\|none] | speed-check-mode ping,tcp:80,tcp:443 |
| response-mode | 首次查询响应模式 | first-ping |模式:[first-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 |
| cname | 指定域名别名 | 无 | cname /domain/target <br />- 表示忽略 <br />指定对应域名的cname | cname /www.example.com/cdn.example.com |
| dns64 | DNS64转换 | 无 | dns64 ip-prefix/mask <br /> ipv6前缀和掩码 | dns64 64:ff9b::/96 |
| 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:- <br />ipset /www.example.com/dns |
| ipset-timeout | 设置 ipset 超时功能启用 | no | [yes\|no] | ipset-timeout yes |
| nftset | 域名 nftset | 无 | nftset /domain/[#4\|#6\|-]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]]-表示忽略ipv4 地址的 family 只支持 inet 和 ipipv6 地址的 family 只支持 inet 和 ip6由于 nft 限制,两种地址只能分开存放于两个 set 中。| nftset /www.example.com/#4:inet#tab#dns4,#6:- |
| ipset-no-speed | 当测速失败时将域名结果设置到ipset集合中 | 无 | ipset \| #[4\|6]:ipset | ipset-no-speed #4:ipset4,#6:ipset6 <br /> ipset-no-speed ipset|
| nftset | 域名 nftset | 无 | nftset /domain/[#4\|#6\|-]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]]<br />-表示忽略;<br />ipv4 地址的 family 只支持 inet 和 ip<br />ipv6 地址的 family 只支持 inet 和 ip6<br />由于 nft 限制,两种地址只能分开存放于两个 set 中。| nftset /www.example.com/#4:inet#tab#dns4,#6:- |
| nftset-timeout | 设置 nftset 超时功能启用 | no | [yes\|no] | nftset-timeout yes |
| nftset-no-speed | 当测速失败时将域名结果设置到nftset集合中 | 无 | nftset-no-speed [#4\|#6]:[family#nftable#nftset][,#[4\|6]:[family#nftable#nftset]]] <br />ipv4 地址的 family 只支持 inet 和 ip <br />ipv6 地址的 family 只支持 inet 和 ip6 <br />由于 nft 限制,两种地址只能分开存放于两个 set 中。| nftset-no-speed #4:inet#tab#set4|
| nftset-debug | 设置 nftset 调试功能启用 | no | [yes\|no] | nftset-debug 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 />[-t\|-nftset]参考nftset配置<br />[-d\|-dualstack-ip-selection]:参考 dualstack-ip-selection<br /> [-no-serve-expired]:禁用过期缓存<br />[-delete]:删除对应的规则 | 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 />[-t\|-nftset]参考nftset配置<br />[-d\|-dualstack-ip-selection]:参考 dualstack-ip-selection<br /> [-no-serve-expired]:禁用过期缓存<br />[-rr-ttl\|-rr-ttl-min\|-rr-ttl-max]: 参考配置rr-ttl, rr-ttl-min, rr-ttl-max<br />[-delete]:删除对应的规则 | 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, nftset等需要指定域名的地方使用使用方式为 /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 |
| ignore-ip | 忽略 IP 地址 | 无 | [ip/subnet],可重复 | ignore-ip 1.2.3.4/16 |
@@ -621,8 +630,9 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
| serve-expired | 过期缓存服务功能 | yes | [yes\|no],开启此功能后,如果有请求时尝试回应 TTL 为 0 的过期记录,并发查询记录,以避免查询等待 |
| serve-expired-ttl | 过期缓存服务最长超时时间 | 0 | 秒0 表示停用超时,大于 0 表示指定的超时的秒数 | serve-expired-ttl 0 |
| serve-expired-reply-ttl | 回应的过期缓存 TTL | 5 | 秒0 表示停用超时,大于 0 表示指定的超时的秒数 | serve-expired-reply-ttl 30 |
| serve-expired-prefetch-time | 过期缓存预查询时间 | 28800 | 秒,到达对应超时时间后预查询时间 | serve-expired-prefetch-time 86400 |
| dualstack-ip-selection | 双栈 IP 优选 | yes | [yes\|no] | dualstack-ip-selection yes |
| dualstack-ip-selection-threshold | 双栈 IP 优选阈值 | 15ms | 单位为毫秒ms | dualstack-ip-selection-threshold [0-1000] |
| dualstack-ip-selection-threshold | 双栈 IP 优选阈值 | 10ms | 单位为毫秒ms | dualstack-ip-selection-threshold [0-1000] |
| user | 进程运行用户 | root | user [username] | user nobody |
| ca-file | 证书文件 | /etc/ssl/<br />certs/ca-certificates.crt | 合法路径字符串 | ca-file /etc/ssl/certs/ca-certificates.crt |
| ca-path | 证书文件路径 | /etc/ssl/certs | 合法路径字符串 | ca-path /etc/ssl/certs |
@@ -868,7 +878,8 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
1. 额外说明
为保证DNS查询结果的位置亲和性可以使用smartdns的`server`代理参数,将对应域名的查询请求,通过代理查询,使结果位置更好。如:
- 为保证DNS查询结果的位置亲和性可以使用smartdns的`server`代理参数,将对应域名的查询请求,通过代理查询,使结果位置更好。如:
```shell
# 增加DNS上游并设置通过名称为proxy的代理查询查询组为pass
@@ -879,6 +890,12 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
domain-rules /example.com/ -ipset proxy -c none -address #6 -nameserver pass
```
- 如需要配合测速自动完成ipset的设置可增加如下配置参数
```shell
ipset-no-speed proxy
```
如果使用openwrt的luci界面可以直接在界面配置相关的域名分流规则。
1. 更多问题

View File

@@ -115,11 +115,14 @@ From the comparison, smartdns found the fastest IP address to visit www.baidu.co
1. **Support IPV4, IPV6 dual stack**
Support IPV4, IPV6 network, support query A, AAAA record, dual-stack IP selection, and filter IPV6 AAAA record.
1. **DNS64**
Support DNS64 translation.
1. **High performance, low resource consumption**
Multi-threaded asynchronous IO mode, cache cache query results.
1. **DNS domain forwarding**
Support DNS forwarding, ipset and nftables.
1. **DNS domain forwarding**
Support DNS forwarding, ipset and nftables. Support setting the domain result to ipset and nftset set when speed check fails.
## Architecture
@@ -164,10 +167,13 @@ Download the matching version of the SmartDNS installation package. The correspo
|openwrt|smartdns.xxxxxxxx.arm-openwrt-all.ipk|Support the arm architecture for openwrt。
|openwrt LUCI|luci-app-smartdns.xxxxxxxxx.all.ipk|Openwrt management interface.
|openwrt LUCI|luci-app-smartdns.xxxxxxxxx.all-luci-compat-all|Compat Openwrt management interface for early openwrt.
|Windows|smartdns-rs https://github.com/mokeyish/smartdns-rs| Rust Version SmartDNS |
|MacOS|smartdns-rs https://github.com/mokeyish/smartdns-rs| Rust Version SmartDNS |
- The released packages are statically compiled. If you need a small size package, please compile it yourself or obtain it from the openwrt / entware repository.
- **Please download from the Release page: [Download here](https://github.com/pymumu/smartdns/releases)**
- **Please download from the Release page: [Download here](https://github.com/pymumu/smartdns/releases)**
```shell
https://github.com/pymumu/smartdns/releases
@@ -471,7 +477,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
1. Install smartdns
download install package `smartdns.xxxxxxxx.x86_64-linux-all.tar.gz`and unzip to the `D:\` directory, after decompression, the directory is as follows:
download install package `smartdns.xxxxxxxx.x86_64-linux-all.tar.gz`, and unzip to the `D:\` directory, after decompression, the directory is as follows:
```shell
D:\SMARTDNS
@@ -535,7 +541,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|--|--|--|--|--|
|server-name|DNS name|host name/smartdns|any string like hostname|server-name smartdns
|bind|DNS listening port number|[::]:53|Support binding multiple ports<br />`IP:PORT@DEVICE`: server IP, port number, and device. <br />`[-group]`: The DNS server group used when requesting. <br />`[-no-rule-addr]`: Skip the address rule. <br />`[-no-rule-nameserver]`: Skip the Nameserver rule. <br />`[-no-rule-ipset]`: Skip the Ipset or nftset rules. <br />`[-no-rule-soa]`: Skip address SOA(#) rules.<br />`[-no-dualstack-selection]`: Disable dualstack ip selection.<br />`[-no-speed-check]`: Disable speed measurement. <br />`[-no-cache]`: stop caching |bind :53@eth0
|bind-tcp|TCP mode DNS listening port number|[::]:53|Support binding multiple ports<br />`IP:PORT@DEVICE`: server IP, port number and device. <br />`[-group]`: The DNS server group used when requesting. <br />`[-no-rule-addr]`: Skip the address rule. <br />`[-no-rule-nameserver]`: Skip the Nameserver rule. <br />`[-no-rule-ipset]`: Skip the Ipset or nftset rules. <br />`[-no-rule-soa]`: Skip address SOA(#) rules.<br />`[-no-dualstack-selection]`: Disable dualstack ip selection.<br />`[-no-speed-check]`: Disable speed measurement. <br />`[-no-cache]`: stop caching |bind-tcp :53
|bind-tcp|TCP mode DNS listening port number|[::]:53|Support binding multiple ports<br />`IP:PORT@DEVICE`: server IP, port number and device. <br />`[-group]`: The DNS server group used when requesting. <br />`[-no-rule-addr]`: Skip the address rule. <br />`[-no-rule-nameserver]`: Skip the Nameserver rule. <br />`[-no-rule-ipset]`: Skip the ipset or nftset rules. <br />`[-no-rule-soa]`: Skip address SOA(#) rules.<br />`[-no-dualstack-selection]`: Disable dualstack ip selection.<br />`[-no-speed-check]`: Disable speed measurement. <br />`[-no-cache]`: stop caching |bind-tcp :53
|cache-size|Domain name result cache number|512|integer|cache-size 512
|cache-persist|enable persist cache|Auto: Enabled if the location of `cache-file` has more than 128MB of free space.|[yes\|no]|cache-persist yes
|cache-file|cache persist file|/tmp/<br />smartdns.cache|path|cache-file /tmp/smartdns.cache
@@ -557,35 +563,40 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|audit-num|archived audit log number|2|Integer, 0 means turn off the log|audit-num 2
|audit-file-mode|archived audit log file mode|0640|Integer|audit-file-mode 644
|conf-file|additional conf file|None|File path|conf-file /etc/smartdns/smartdns.more.conf
|server|Upstream UDP DNS server|None|Repeatable <br />`[ip][:port]\|URL`: Server IP, port optional OR URL. <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. <br />`[-set-mark mark]`set mark on packets <br /> `[-proxy name]`: set proxy server| server 8.8.8.8:53 -blacklist-ip<br />server tls://8.8.8.8
|server-tcp|Upstream TCP DNS server|None|Repeatable <br />`[ip][:port]`: Server IP, port optional. <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 <br />`[-set-mark mark]`set mark on packets <br /> `[-proxy name]`: set proxy server| server-tcp 8.8.8.8:53
|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. `-` to disable SNI 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 <br /> `[-set-mark mark]`set mark on packets <br /> `[-proxy name]`: set proxy server| 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 <br /> `[-set-mark mark]`set mark on packets <br /> `[-proxy name]`: set proxy server| server-https <https://cloudflare-dns.com/dns-query>
|server|Upstream UDP DNS server|None|Repeatable <br />`[ip][:port]\|URL`: Server IP, port optional OR URL. <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. <br />`[-set-mark mark]`: set mark on packets <br /> `[-proxy name]`: set proxy server| server 8.8.8.8:53 -blacklist-ip<br />server tls://8.8.8.8
|server-tcp|Upstream TCP DNS server|None|Repeatable <br />`[ip][:port]`: Server IP, port optional. <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 <br />`[-set-mark mark]`: set mark on packets <br /> `[-proxy name]`: set proxy server| server-tcp 8.8.8.8:53
|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. `-` to disable SNI 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 <br /> `[-set-mark mark]`: set mark on packets <br /> `[-proxy name]`: set proxy server| 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 <br /> `[-set-mark mark]`: set mark on packets <br /> `[-proxy name]`: set proxy server| server-https <https://cloudflare-dns.com/dns-query>
|proxy-server| proxy server | None | Repeatable. <br />`proxy-server URL` <br />[URL]: `[socks5\|http]://[username:password@]host:port`<br />[-name]: proxy server name. |proxy-server socks5://user:pass@1.2.3.4:1080 -name proxy|
|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: [first-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
|cname|set cname to domain| None | cname /domain/target <br />- for ignore <br />set cname to domain. | cname /www.example.com/cdn.example.com |
|dns64|dns64 translation | None | dns64 ip-prefix/mask <br /> ipv6 prefix and mask. | dns64 64:ff9b::/96 |
|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-timeout|ipset timeout enable|no|[yes\|no]|ipset-timeout yes
|nftset|Domain nftset|None|nftset /domain/[#4\|#6\|-]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]], `-` to ignore; the valid families are inet and ip for ipv4 addresses while the valid ones are inet and ip6 for ipv6 addresses; due to the limitation of nft, two types of addresses have to be stored in two sets|nftset /www.example.com/#4:inet#tab#dns4,#6:-
|ipset-no-speed|When speed check fails, set the ip address of the domain name to the ipset | None | ipset \| #[4\|6]:ipset | ipset-no-speed #4:ipset4,#6:ipset6 <br /> ipset-no-speed ipset|
|nftset|Domain nftset|None|nftset /domain/[#4\|#6\|-]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]]<br /> `-` to ignore<br />the valid families are inet and ip for ipv4 addresses while the valid ones are inet and ip6 for ipv6 addresses <br />due to the limitation of nftable <br />two types of addresses have to be stored in two sets|nftset /www.example.com/#4:inet#tab#dns4,#6:-
|nftset-timeout|nftset timeout enable|no|[yes\|no]|nftset-timeout yes
|nftset-no-speed|When speed check fails, set the ip address of the domain name to the nftset | None | nftset-no-speed [#4\|#6]:[family#nftable#nftset][,#[4\|6]:[family#nftable#nftset]]] <br />the valid families are inet and ip for ipv4 addresses while the valid ones are inet and ip6 for ipv6 addresses <br />due to the limitation of nftable <br />two types of addresses have to be stored in two sets| nftset-no-speed #4:inet#tab#set4|
|nftset-debug|nftset debug enable|no|[yes\|no]|nftset-debug 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 `nftset`<br />[-t\|-nftset]: same as parameter `nftset`<br />[-d\|-dualstack-ip-selection]: same as parameter `dualstack-ip-selection`<br /> [-no-serve-expired]disable serve expired<br />[-delete]delete rule|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, nftset, example: /domain-set:[name]/ | domain-set -name set -type list -file /path/to/list <br /> address /domain-set:set/1.2.4.8 |
|domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]<br />[-c\|-speed-check-mode]: set speed check mode, same 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 `nftset`<br />[-t\|-nftset]: same as parameter `nftset`<br />[-d\|-dualstack-ip-selection]: same as parameter `dualstack-ip-selection`<br /> [-no-serve-expired]: disable serve expired<br />[-rr-ttl\|-rr-ttl-min\|-rr-ttl-max]: same as parameter: rr-ttl, rr-ttl-min, rr-ttl-max<br />[-delete]: delete rule|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, nftset, 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
|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
|blacklist-ip|ip blacklist|None|[ip/subnet], RepeatableWhen the filtering server responds IPs in the IP blacklist, The result will be discarded directly| blacklist-ip 1.2.3.4/16
|whitelist-ip|ip whitelist|None|[ip/subnet], Repeatable, When the filtering server responds IPs in the IP whitelist, only result in whitelist will be accepted| whitelist-ip 1.2.3.4/16
|blacklist-ip|ip blacklist|None|[ip/subnet], Repeatable, When the filtering server responds IPs in the IP blacklist, The result will be discarded directly| blacklist-ip 1.2.3.4/16
|force-AAAA-SOA|force AAAA query return SOA|no|[yes\|no]|force-AAAA-SOA yes
|force-qtype-SOA|force specific qtype return SOA|qtype id|[qtypeid \| ...]|force-qtype-SOA 65 28
|prefetch-domain|domain prefetch feature|no|[yes\|no]|prefetch-domain yes
|dnsmasq-lease-file|Support reading dnsmasq dhcp file to resolve local hostname|None|dnsmasq dhcp lease file| dnsmasq-lease-file /var/lib/misc/dnsmasq.leases
|serve-expired|Cache serve expired feature|yes|[yes\|no], Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish.|serve-expired yes
|serve-expired-ttl|Cache serve expired limit TTL|0|second0disable> 0 seconds after expiration|serve-expired-ttl 0
|serve-expired-reply-ttl|TTL value to use when replying with expired data|5|second0disable> 0 seconds after expiration|serve-expired-reply-ttl 30
|serve-expired-ttl|Cache serve expired limit TTL|0|second, 0: disable, > 0 seconds after expiration|serve-expired-ttl 0
|serve-expired-reply-ttl|TTL value to use when replying with expired data|5|second, 0: disable, > 0 seconds after expiration|serve-expired-reply-ttl 30
|serve-expired-prefetch-time| Prefetch time when serve expired | 28800 | secondprefetch time | serve-expired-prefetch-time 86400 |
|dualstack-ip-selection|Dualstack ip selection|yes|[yes\|no]|dualstack-ip-selection yes
|dualstack-ip-selection-threshold|Dualstack ip select thresholds|15ms|millisecond|dualstack-ip-selection-threshold [0-1000]
|dualstack-ip-selection-threshold|Dualstack ip select thresholds|10ms|millisecond|dualstack-ip-selection-threshold [0-1000]
|user|run as user|root|user [username]|user nobody
|ca-file|certificate file|/etc/ssl/certs/<br />ca-certificates.crt|path|ca-file /etc/ssl/certs/ca-certificates.crt
|ca-path|certificates path|/etc/ssl/certs|path|ca-path /etc/ssl/certs

View File

@@ -105,7 +105,7 @@ force-qtype-SOA 65
# dualstack-ip-selection-threshold [num] (0~1000)
# dualstack-ip-allow-force-AAAA [yes|no]
# dualstack-ip-selection [yes|no]
# dualstack-ip-selection yes
# dualstack-ip-selection no
# edns client subnet
# edns-client-subnet [ip/subnet]
@@ -226,6 +226,13 @@ log-level info
# address /www.example.com/-, ignore address, query from upstream, suffix 4, for ipv4, 6 for ipv6, none for all
# address /www.example.com/#, return SOA to client, suffix 4, for ipv4, 6 for ipv6, none for all
# specific cname to domain
# cname /domain/target
# enalbe DNS64 feature
# dns64 [ip/subnet]
# dns64 64:ff9b::/96
# enable ipset timeout by ttl feature
# ipset-timeout [yes]
@@ -234,10 +241,18 @@ log-level info
# ipset /www.example.com/block, set ipset with ipset name of block
# ipset /www.example.com/-, ignore this domain
# add to ipset when ping is unreachable
# ipset-no-speed ipsetname
# ipset-no-speed pass
# enable nftset timeout by ttl feature
# nftset-timeout [yes|no]
# nftset-timeout yes
# add to nftset when ping is unreachable
# nftset-no-speed [#4:ip#table#set,#6:ipv6#table#setv6]
# nftset-no-speed #4:ip#table#set
# enable nftset debug, check nftset setting result, output log when error.
# nftset-debug [yes|no]
# nftset-debug yes

View File

@@ -82,6 +82,9 @@ msgstr "协议类型"
msgid "DNS domain result cache size"
msgstr "缓存DNS的结果缓存大小配置零则不缓存"
msgid "DNS64 Server Settings"
msgstr "DNS64服务器配置"
msgid "Description"
msgstr "描述"
@@ -231,6 +234,12 @@ msgstr "IPSet名称"
msgid "IPset name."
msgstr "IPSet名称。"
msgid "Ipset name, Add domain result to ipset when speed check fails."
msgstr "IPset名称当测速失败时将查询到的结果添加到对应的IPSet集合中。"
msgid "ipset name format error, format: [#[4|6]:]ipsetname"
msgstr "IPset名称格式错误格式[#[4|6]:]ipsetname"
msgid "If you like this software, please buy me a cup of coffee."
msgstr "如果本软件对你有帮助,请给作者加个蛋。"
@@ -240,7 +249,7 @@ msgstr "包含配置文件"
msgid ""
"Include other config files from /etc/smartdns/conf.d or custom path, can be "
"downloaded from the download page."
msgstr "包含配置文件,路径为/etc/smartdns/conf.d或自定义配置文件路径可以从下载页"
msgstr "包含配置文件,路径为/etc/smartdns/conf.d或自定义配置文件路径可以从下载页配置自动下载。"
msgid "List of files to download."
msgstr "下载的文件列表。"
@@ -275,6 +284,15 @@ msgstr "NFTSet名称格式错误格式[#[4|6]:[family#table#set]]"
msgid "NFTset name, format: [#[4|6]:[family#table#set]]"
msgstr "NFTSet名称格式[#[4|6]:[family#table#set]]"
msgid "Nftset name, Add domain result to nftset when speed check fails, format: [#[4|6]:[family#table#set]]"
msgstr "NFTset名称当测速失败时将查询到的结果添加到对应的NFTSet集合中。"
msgid "No Speed IPset Name"
msgstr "无速度时IPSet名称"
msgid "No Speed NFTset Name"
msgstr "无速度时NFTSet名称"
msgid "NOT RUNNING"
msgstr "未运行"

View File

@@ -34,6 +34,7 @@ s.anonymous = true
s:tab("settings", translate("General Settings"))
s:tab("advanced", translate('Advanced Settings'))
s:tab("seconddns", translate("Second Server Settings"))
s:tab("dns64", translate("DNS64 Server Settings"))
s:tab("proxy", translate("Proxy Server Settings"))
s:tab("custom", translate("Custom Settings"))
@@ -56,6 +57,14 @@ o.default = 53
o.datatype = "port"
o.rempty = false
-- 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
---- Speed check mode;
o = s:taboption("advanced", Value, "speed_check_mode", translate("Speed Check Mode"), translate("Smartdns speed check mode."));
o.rmempty = true;
@@ -187,14 +196,6 @@ o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
-- Automatically Set Dnsmasq
o = s:taboption("advanced", Flag, "auto_set_dnsmasq", translate("Automatically Set Dnsmasq"), translate("Automatically set as upstream of dnsmasq when port changes."))
o.rmempty = false
o.default = o.enabled
o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "0"
end
-- Force AAAA SOA
o = s:taboption("advanced", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
o.rmempty = false
@@ -211,6 +212,31 @@ o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1"
end
---- Ipset no speed.
o = s:taboption("advanced", Value, "ipset_no_speed", translate("No Speed IPset Name"),
translate("Ipset name, Add domain result to ipset when speed check fails."));
o.rmempty = true;
o.datatype = "hostname";
o.rempty = true;
---- NFTset no speed.
o = s:taboption("advanced", Value, "nftset_no_speed", translate("No Speed NFTset Name"),
translate("Nftset name, Add domain result to nftset when speed check fails, format: [#[4|6]:[family#table#set]]"));
o.rmempty = true;
o.datatype = "string";
o.rempty = true;
function o.validate(self, value)
if (value == "") then
return value
end
if (value:match("#[4|6]:[a-zA-Z0-9%-_]+#[a-zA-Z0-9%-_]+#[a-zA-Z0-9%-_]+$")) then
return value
end
return nil, translate("NFTset name format error, format: [#[4|6]:[family#table#set]]")
end
---- rr-ttl
o = s:taboption("advanced", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result."))
o.rempty = true
@@ -346,6 +372,12 @@ function o.validate(self, value)
return value
end
----- dns64 server settings
o = s:taboption("dns64", Value, "dns64", translate("DNS64"));
o.placeholder = "64:ff9b::/96"
o.datatype = 'ip6addr'
o.rmempty = true
----- custom settings
custom = s:taboption("custom", Value, "Custom Settings",
translate(""),

View File

@@ -90,6 +90,9 @@ msgstr "协议类型"
msgid "DNS domain result cache size"
msgstr "缓存DNS的结果缓存大小配置零则不缓存"
msgid "DNS64 Server Settings"
msgstr "DNS64服务器配置"
msgid "default"
msgstr "默认"
@@ -255,6 +258,12 @@ msgstr "IPset名称"
msgid "IPset name."
msgstr "IPSet名称。"
msgid "Ipset name, Add domain result to ipset when speed check fails."
msgstr "IPset名称当测速失败时将查询到的结果添加到对应的IPSet集合中。"
msgid "ipset name format error, format: [#[4|6]:]ipsetname"
msgstr "IPset名称格式错误格式[#[4|6]:]ipsetname"
msgid "If you like this software, please buy me a cup of coffee."
msgstr "如果本软件对你有帮助,请给作者加个蛋。"
@@ -265,7 +274,7 @@ msgid ""
"Include other config files from /etc/smartdns/conf.d or custom path, can be "
"downloaded from the download page."
msgstr ""
"包含配置文件,路径为/etc/smartdns/conf.d或自定义配置文件路径可以从下载页"
"包含配置文件,路径为/etc/smartdns/conf.d或自定义配置文件路径可以从下载页配置自动下载。"
"面配置自动下载。"
msgid "List of files to download."
@@ -301,6 +310,15 @@ msgstr "NFTSet名称格式错误格式[#[4|6]:[family#table#set]]"
msgid "NFTset name, format: [#[4|6]:[family#table#set]]"
msgstr "NFTSet名称格式[#[4|6]:[family#table#set]]"
msgid "Nftset name, Add domain result to nftset when speed check fails, format: [#[4|6]:[family#table#set]]"
msgstr "NFTset名称当测速失败时将查询到的结果添加到对应的NFTSet集合中。"
msgid "No Speed IPset Name"
msgstr "无速度时IPSet名称"
msgid "No Speed NFTset Name"
msgstr "无速度时NFTSet名称"
msgid "NOT RUNNING"
msgstr "未运行"

View File

@@ -131,6 +131,7 @@ return view.extend({
s.tab("settings", _("General Settings"));
s.tab("advanced", _('Advanced Settings'));
s.tab("seconddns", _("Second Server Settings"));
s.tab("dns64", _("DNS64 Server Settings"));
s.tab("files", _("Download Files Setting"), _("Download domain list files for domain-rule and include config files, please refresh the page after download to take effect."));
s.tab("proxy", _("Proxy Server Settings"));
s.tab("custom", _("Custom Settings"));
@@ -155,6 +156,11 @@ return view.extend({
o.default = 53;
o.datatype = "port";
o.rempty = false;
// 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;
///////////////////////////////////////
// advanced settings;
@@ -262,11 +268,6 @@ return view.extend({
o.rmempty = false;
o.default = o.enabled;
// auto-conf-dnsmasq;
o = s.taboption("advanced", 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("advanced", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
o.rmempty = false;
@@ -277,6 +278,48 @@ return view.extend({
o.rmempty = false;
o.default = o.enabled;
// Ipset no speed.
o = s.taboption("advanced", form.Value, "ipset_no_speed", _("No Speed IPset Name"),
_("Ipset name, Add domain result to ipset when speed check fails."));
o.rmempty = true;
o.datatype = "string";
o.rempty = true;
o.validate = function (section_id, value) {
if (value == "") {
return true;
}
var ipset = value.split(",")
for (var i = 0; i < ipset.length; i++) {
if (!ipset[i].match(/^(#[4|6]:)?[a-zA-Z0-9\-_]+$/)) {
return _("ipset name format error, format: [#[4|6]:]ipsetname");
}
}
return true;
}
// NFTset no speed.
o = s.taboption("advanced", form.Value, "nftset_no_speed", _("No Speed NFTset Name"),
_("Nftset name, Add domain result to nftset when speed check fails, format: [#[4|6]:[family#table#set]]"));
o.rmempty = true;
o.datatype = "string";
o.rempty = true;
o.validate = function (section_id, value) {
if (value == "") {
return true;
}
var nftset = value.split(",")
for (var i = 0; i < nftset.length; i++) {
if (!nftset[i].match(/^#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) {
return _("NFTset name format error, format: [#[4|6]:[family#table#set]]");
}
}
return true;
}
// rr-ttl;
o = s.taboption("advanced", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result."));
o.rempty = true;
@@ -388,6 +431,14 @@ return view.extend({
o.rmempty = false;
o.default = o.disabled;
///////////////////////////////////////
// DNS64 Settings
///////////////////////////////////////
o = s.taboption("dns64", form.Value, "dns64", _("DNS64"));
o.placeholder = "64:ff9b::/96";
o.datatype = "ip6addr";
o.rempty = true;
///////////////////////////////////////
// download Files Settings
///////////////////////////////////////
@@ -720,8 +771,22 @@ return view.extend({
o = s.taboption("forwarding", form.Value, "ipset_name", _("IPset Name"), _("IPset name."));
o.rmempty = true;
o.datatype = "hostname";
o.datatype = "string";
o.rempty = true;
o.validate = function (section_id, value) {
if (value == "") {
return true;
}
var ipset = value.split(",")
for (var i = 0; i < ipset.length; i++) {
if (!ipset[i].match(/^(#[4|6]:)?[a-zA-Z0-9\-_]+$/)) {
return _("ipset name format error, format: [#[4|6]:]ipsetname");
}
}
return true;
}
o = s.taboption("forwarding", form.Value, "nftset_name", _("NFTset Name"), _("NFTset name, format: [#[4|6]:[family#table#set]]"));
o.rmempty = true;
@@ -734,7 +799,7 @@ return view.extend({
var nftset = value.split(",")
for (var i = 0; i < nftset.length; i++) {
if (!nftset[i].match(/#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) {
if (!nftset[i].match(/^#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) {
return _("NFTset name format error, format: [#[4|6]:[family#table#set]]");
}
}

View File

@@ -169,6 +169,7 @@ load_server()
local section="$1"
local ADDITIONAL_ARGS=""
local DNS_ADDRESS=""
local IS_URI="0"
config_get_bool enabled "$section" "enabled" "1"
config_get port "$section" "port" ""
@@ -202,7 +203,9 @@ load_server()
SERVER="server-https"
fi
if echo "$ip" | grep ":" | grep -q -v "https://" >/dev/null 2>&1; then
if echo "$ip" | grep "://" >/dev/null 2>&1; then
IS_URI="1"
elif echo "$ip" | grep ":"; then
if ! echo "$ip" | grep -q "\\[" >/dev/null 2>&1; then
ip="[$ip]"
fi
@@ -220,14 +223,12 @@ load_server()
[ -z "$set_mark" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -set-mark $set_mark"
[ "$use_proxy" = "0" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -proxy default-proxy"
if [ -z "$port" ]; then
if [ -z "$port" ] || [ "$IS_URI" = "1" ]; then
DNS_ADDRESS="$ip"
else
DNS_ADDRESS="$ip:$port"
fi
[ "$type" = "https" ] && DNS_ADDRESS="$ip"
conf_append "$SERVER" "$DNS_ADDRESS $ADDITIONAL_ARGS $addition_arg"
}
@@ -479,6 +480,7 @@ load_service()
config_get port "$section" "port" "53"
config_get ipv6_server "$section" "ipv6_server" "1"
config_get tcp_server "$section" "tcp_server" "1"
config_get server_flags "$section" "server_flags" ""
config_get speed_check_mode "$section" "speed_check_mode" ""
[ ! -z "$speed_check_mode" ] && conf_append "speed-check-mode" "$speed_check_mode"
@@ -506,6 +508,12 @@ load_service()
config_get auto_set_dnsmasq "$section" "auto_set_dnsmasq" "1"
config_get ipset_no_speed "$section" "ipset_no_speed" ""
[ -z "$ipset_no_speed" ] || conf_append "ipset-no-speed" "$ipset_no_speed"
config_get nftset_no_speed "$section" "nftset_no_speed" ""
[ -z "$nftset_no_speed" ] || conf_append "nftset-no-speed" "$nftset_no_speed"
config_get rr_ttl "$section" "rr_ttl" ""
[ -z "$rr_ttl" ] || conf_append "rr-ttl" "$rr_ttl"
@@ -556,6 +564,9 @@ load_service()
config_get proxy_server "$section" "proxy_server" ""
[ -z "$proxy_server" ] || conf_append "proxy-server" "$proxy_server -name default-proxy"
config_get dns64 "$section" "dns64" ""
[ -z "$dns64" ] || conf_append "dns64" "$dns64"
config_get redirect "$section" "redirect" ""
config_get old_port "$section" "old_port" "0"
config_get old_enabled "$section" "old_enabled" "0"
@@ -622,7 +633,7 @@ load_service()
[ "$auto_set_dnsmasq" = "0" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0"
}
conf_append_bind "$port" "$device" "$tcp_server" "$ipv6_server" "$ARGS"
conf_append_bind "$port" "$device" "$tcp_server" "$ipv6_server" "$server_flags"
load_second_server "$section"

View File

@@ -343,28 +343,28 @@ case "$1" in
$SMARTDNS_BIN -c "$SMARTDNS_CONF" -p $SMARTDNS_PID
if [ $? -ne 0 ]; then
clear_rule
exit 1
fi
;;
status)
pid="$(cat $SMARTDNS_PID |head -n 1 2>/dev/null)"
if [ -z "$pid" ]; then
echo "smartdns not running."
return 0
exit 0
fi
if [ -d "/proc/$pid" ]; then
echo "smartdns running"
return 0;
echo "smartdns is running"
exit 0
fi
echo "smartdns not running."
return 0;
exit 0
;;
stop)
clear_rule
pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
if [ -z "$pid" ]; then
echo "smartdns not running."
return 0
exit 0
fi
kill -15 "$pid" 2>/dev/null
@@ -379,17 +379,17 @@ case "$1" in
do
pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
if [ -z "$pid" ]; then
return 0
break
fi
if [ ! -d "/proc/$pid" ]; then
return 0
break
fi
stat="$(cat /proc/${pid}/stat | awk '{print $3}' 2>/dev/null)"
if [ "$stat" = "Z" ]; then
$SLEEP $SLEEPTIME
return 0
break
fi
$SLEEP $SLEEPTIME 2>/dev/null
@@ -397,11 +397,15 @@ case "$1" in
done
kill -9 "$pid" 2>/dev/null
clear_rule
exit 0
;;
restart)
$0 stop
$0 start
;;
reload)
;;
enable)
nvram set apps_state_enable=2
nvram set apps_state_error=0

View File

@@ -20,7 +20,12 @@ OBJS=smartdns.o fast_ping.o dns_client.o dns_server.o dns.o util.o tlog.o dns_co
# cflags
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
ifdef DEBUG
CFLAGS = -g
else
CFLAGS = -O2
endif
CFLAGS +=-Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables -Wmissing-prototypes -Wshadow -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough
endif
override CFLAGS +=-Iinclude
override CFLAGS += -DBASE_FILE_NAME='"$(notdir $<)"'
@@ -34,9 +39,9 @@ override CXXFLAGS +=-Iinclude
# ldflags
ifeq ($(STATIC), yes)
override LDFLAGS += -lssl -lcrypto -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -ldl -static
override LDFLAGS += -lssl -lcrypto -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -ldl -static
else
override LDFLAGS += -lssl -lcrypto -lpthread -ldl
override LDFLAGS += -lssl -lcrypto -lpthread -ldl
endif
.PHONY: all clean

View File

@@ -42,6 +42,8 @@
(void)(expr); \
} while (0)
#define member_size(type, member) sizeof(((type *)0)->member)
/* read short and move pointer */
static unsigned short _dns_read_short(unsigned char **buffer)
{
@@ -111,7 +113,7 @@ static int _dns_get_domain_from_packet(unsigned char *packet, int packet_size, u
/*[len]string[len]string...[0]0 */
while (1) {
if (ptr >= packet + packet_size || ptr < packet || output_len >= size - 1 || ptr_jump > 4) {
if (ptr >= packet + packet_size || ptr < packet || output_len >= size - 1 || ptr_jump > 32) {
return -1;
}
@@ -1639,12 +1641,12 @@ static int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs)
return 0;
}
static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *ecs)
static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *ecs, int opt_len)
{
// TODO
int len = 0;
if (_dns_left_len(context) < 4) {
if (opt_len < 4) {
return -1;
}
@@ -1668,31 +1670,30 @@ static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *
return 0;
}
static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_cookie *cookie)
static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_cookie *cookie, int opt_len)
{
// TODO
int len = _dns_left_len(context);
if (len < 8) {
if (opt_len < (int)member_size(struct dns_opt_cookie, client_cookie)) {
return -1;
}
len = 8;
int len = 8;
memcpy(cookie->client_cookie, context->ptr, len);
context->ptr += len;
len = _dns_left_len(context);
if (len == 0) {
opt_len -= len;
if (opt_len <= 0) {
cookie->server_cookie_len = 0;
return 0;
}
if (len < 8) {
if (opt_len < 8 || opt_len > (int)member_size(struct dns_opt_cookie, server_cookie)) {
return -1;
}
memcpy(cookie->server_cookie, context->ptr, len);
cookie->server_cookie_len = len;
context->ptr += len;
memcpy(cookie->server_cookie, context->ptr, opt_len);
cookie->server_cookie_len = opt_len;
context->ptr += opt_len;
tlog(TLOG_DEBUG, "OPT COOKIE");
return 0;
@@ -1859,8 +1860,8 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
}
if (errcode != 0) {
tlog(TLOG_ERROR, "extend rcode invalid.");
return -1;
tlog(TLOG_DEBUG, "extend rcode invalid, %d", errcode);
return 0;
}
while (context->ptr - start < rr_len) {
@@ -1881,7 +1882,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
switch (opt_code) {
case DNS_OPT_T_ECS: {
struct dns_opt_ecs ecs;
ret = _dns_decode_opt_ecs(context, &ecs);
ret = _dns_decode_opt_ecs(context, &ecs, opt_len);
if (ret != 0) {
tlog(TLOG_ERROR, "decode ecs failed.");
return -1;
@@ -1895,7 +1896,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
} break;
case DNS_OPT_T_COOKIE: {
struct dns_opt_cookie cookie;
ret = _dns_decode_opt_cookie(context, &cookie);
ret = _dns_decode_opt_cookie(context, &cookie, opt_len);
if (ret != 0) {
tlog(TLOG_ERROR, "decode cookie failed.");
return -1;
@@ -2254,6 +2255,16 @@ static int _dns_encode_qd(struct dns_context *context, struct dns_rrs *rrs)
return -1;
}
if (domain[0] == '-') {
/* for google and cloudflare */
unsigned char *ptr = context->ptr - 7;
memcpy(ptr, "\xC0\x12", 2);
ptr += 2;
_dns_write_short(&ptr, qtype);
_dns_write_short(&ptr, qclass);
context->ptr = ptr;
}
return 0;
}

View File

@@ -198,7 +198,7 @@ struct dns_opt_ecs {
unsigned char addr[DNS_RR_AAAA_LEN];
} __attribute__((packed));
/* OPT COOLIE */
/* OPT COOKIE */
struct dns_opt_cookie {
char server_cookie_len;
unsigned char client_cookie[8];

View File

@@ -329,7 +329,7 @@ static void _dns_cache_remove_by_domain(struct dns_cache_key *cache_key)
continue;
}
if (strncmp(dns_cache->info.dns_group_name, cache_key->dns_group_name, DNS_MAX_CNAME_LEN) != 0) {
if (strncmp(dns_cache->info.dns_group_name, cache_key->dns_group_name, DNS_GROUP_NAME_LEN) != 0) {
continue;
}
@@ -408,6 +408,7 @@ int dns_cache_insert(struct dns_cache_key *cache_key, int ttl, int speed, int no
ttl = DNS_CACHE_TTL_MIN;
}
memset(&info, 0, sizeof(info));
info.hitnum = 3;
safe_strncpy(info.domain, cache_key->domain, DNS_MAX_CNAME_LEN);
info.qtype = cache_key->qtype;

View File

@@ -41,13 +41,14 @@
#include <netinet/ip_icmp.h>
#include <netinet/tcp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/random.h>
#include <sys/eventfd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -97,6 +98,7 @@ struct dns_server_info {
/* server type */
dns_server_type_t type;
long long so_mark;
int drop_packet_latency_ms;
/* client socket */
int fd;
@@ -118,6 +120,7 @@ struct dns_server_info {
time_t last_send;
time_t last_recv;
unsigned long send_tick;
int prohibit;
/* server addr info */
@@ -152,6 +155,8 @@ struct dns_server_pending {
unsigned int has_v6;
unsigned int query_v4;
unsigned int query_v6;
unsigned int has_soa;
/* server type */
dns_server_type_t type;
int retry_cnt;
@@ -192,7 +197,6 @@ struct dns_client {
/* query list */
struct list_head dns_request_list;
pthread_cond_t run_cond;
atomic_t run_period;
atomic_t dns_server_num;
@@ -204,6 +208,8 @@ struct dns_client {
pthread_mutex_t domain_map_lock;
DECLARE_HASHTABLE(domain_map, 6);
DECLARE_HASHTABLE(group, 4);
int fd_wakeup;
};
/* dns replied server info */
@@ -260,6 +266,8 @@ static pthread_mutex_t pending_server_mutex = PTHREAD_MUTEX_INITIALIZER;
static int dns_client_has_bootstrap_dns = 0;
static int _dns_client_send_udp(struct dns_server_info *server_info, void *packet, int len);
static void _dns_client_clear_wakeup_event(void);
static void _dns_client_do_wakeup_event(void);
static ssize_t _ssl_read(struct dns_server_info *server, void *buff, int num)
{
@@ -439,7 +447,7 @@ errout:
}
/* check whether server exists */
static int _dns_client_server_exist(const char *server_ip, int port, dns_server_type_t server_type)
static int _dns_client_server_exist(const char *server_ip, int port, dns_server_type_t server_type, struct client_dns_server_flags *flags)
{
struct dns_server_info *server_info = NULL;
struct dns_server_info *tmp = NULL;
@@ -450,6 +458,10 @@ static int _dns_client_server_exist(const char *server_ip, int port, dns_server_
continue;
}
if (memcmp(&server_info->flags, flags, sizeof(*flags)) == 0) {
continue;
}
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN) != 0) {
continue;
}
@@ -1021,7 +1033,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
}
/* if server exist, return */
if (_dns_client_server_exist(server_ip, port, server_type) == 0) {
if (_dns_client_server_exist(server_ip, port, server_type, flags) == 0) {
return 0;
}
@@ -1054,6 +1066,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
server_info->skip_check_cert = skip_check_cert;
server_info->prohibit = 0;
server_info->so_mark = flags->set_mark;
server_info->drop_packet_latency_ms = flags->drop_packet_latency_ms;
safe_strncpy(server_info->proxy_name, flags->proxyname, sizeof(server_info->proxy_name));
pthread_mutex_init(&server_info->lock, NULL);
memcpy(&server_info->flags, flags, sizeof(server_info->flags));
@@ -1332,9 +1345,8 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type
atomic_set(&client.run_period, 1);
pthread_mutex_unlock(&pending_server_mutex);
pthread_mutex_lock(&client.domain_map_lock);
pthread_cond_signal(&client.run_cond);
pthread_mutex_unlock(&client.domain_map_lock);
_dns_client_do_wakeup_event();
return 0;
errout:
if (pending) {
@@ -1509,7 +1521,7 @@ static void _dns_client_check_tcp(void)
}
if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
if (server_info->last_send + DNS_TCP_CONNECT_TIMEOUT < now) {
if (server_info->last_recv + DNS_TCP_CONNECT_TIMEOUT < now) {
tlog(TLOG_DEBUG, "server %s connect timeout.", server_info->ip);
_dns_client_close_socket(server_info);
}
@@ -2174,6 +2186,11 @@ static int _dns_client_process_udp_proxy(struct dns_server_info *server_info, st
return ret;
}
int latency = get_tick_count() - server_info->send_tick;
if (latency < server_info->drop_packet_latency_ms) {
return 0;
}
tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d",
get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len);
@@ -2259,6 +2276,11 @@ static int _dns_client_process_udp(struct dns_server_info *server_info, struct e
/* update recv time */
time(&server_info->last_recv);
int latency = get_tick_count() - server_info->send_tick;
if (latency < server_info->drop_packet_latency_ms) {
return 0;
}
/* processing dns packet */
if (_dns_client_recv(server_info, inpacket, len, (struct sockaddr *)&from, from_len) != 0) {
return -1;
@@ -3263,6 +3285,9 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
continue;
}
server_info->prohibit = 0;
if (now - 60 > server_info->last_send) {
_dns_client_close_socket(server_info);
}
}
total_server++;
tlog(TLOG_DEBUG, "send query to server %s", server_info->ip);
@@ -3274,6 +3299,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
}
atomic_inc(&query->dns_request_sent);
errno = 0;
switch (server_info->type) {
case DNS_SERVER_UDP:
/* udp query */
@@ -3324,6 +3350,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
continue;
}
time(&server_info->last_send);
server_info->send_tick = get_tick_count();
}
pthread_mutex_unlock(&client.server_list_lock);
@@ -3524,7 +3551,7 @@ int dns_client_query(const char *domain, int qtype, dns_client_callback callback
query->qtype = qtype;
query->send_tick = 0;
query->has_result = 0;
if (getrandom(&query->sid, sizeof(query->sid), GRND_NONBLOCK) != sizeof(query->sid)) {
if (RAND_bytes((unsigned char *)&query->sid, sizeof(query->sid)) != 1) {
query->sid = random();
}
query->server_group = _dns_client_get_dnsserver_group(group_name);
@@ -3558,7 +3585,7 @@ int dns_client_query(const char *domain, int qtype, dns_client_callback callback
pthread_mutex_lock(&client.domain_map_lock);
if (hash_hashed(&query->domain_node)) {
if (list_empty(&client.dns_request_list)) {
pthread_cond_signal(&client.run_cond);
_dns_client_do_wakeup_event();
}
list_add_tail(&query->dns_request_list, &client.dns_request_list);
@@ -3614,11 +3641,16 @@ static int _dns_client_pending_server_resolve(const char *domain, dns_rtcode_t r
struct dns_server_pending *pending = user_ptr;
int ret = 0;
if (rtcode == DNS_RC_NXDOMAIN) {
pending->has_soa = 1;
}
if (addr_type == DNS_T_A) {
pending->ping_time_v4 = -1;
if (rtcode == DNS_RC_NOERROR) {
pending->has_v4 = 1;
pending->ping_time_v4 = ping_time;
pending->has_soa = 0;
safe_strncpy(pending->ipv4, ip, DNS_HOSTNAME_LEN);
}
} else if (addr_type == DNS_T_AAAA) {
@@ -3626,6 +3658,7 @@ static int _dns_client_pending_server_resolve(const char *domain, dns_rtcode_t r
if (rtcode == DNS_RC_NOERROR) {
pending->has_v6 = 1;
pending->ping_time_v6 = ping_time;
pending->has_soa = 0;
safe_strncpy(pending->ipv6, ip, DNS_HOSTNAME_LEN);
}
} else {
@@ -3759,6 +3792,12 @@ static void _dns_client_add_pending_servers(void)
continue;
}
if (pending->has_soa && dnsserver_ip == NULL) {
tlog(TLOG_WARN, "add pending DNS server %s failed, no such host.", pending->host);
_dns_client_server_pending_remove(pending);
continue;
}
if (pending->retry_cnt - 1 > DNS_PENDING_SERVER_RETRY || add_success) {
if (add_success == 0) {
tlog(TLOG_WARN, "add pending DNS server %s failed.", pending->host);
@@ -3795,15 +3834,12 @@ static void _dns_client_period_run_second(void)
_dns_client_add_pending_servers();
}
static void _dns_client_period_run(void)
static void _dns_client_period_run(unsigned int msec)
{
struct dns_query_struct *query = NULL;
struct dns_query_struct *tmp = NULL;
static unsigned int msec = 0;
msec++;
LIST_HEAD(check_list);
unsigned long now = get_tick_count();
/* get query which timed out to check list */
@@ -3846,9 +3882,11 @@ static void *_dns_client_work(void *arg)
int i = 0;
unsigned long now = {0};
unsigned long last = {0};
unsigned int msec = 0;
unsigned int sleep = 100;
int sleep_time = 0;
unsigned long expect_time = 0;
int unused __attribute__((unused));
sleep_time = sleep;
now = get_tick_count() - sleep;
@@ -3861,11 +3899,17 @@ static void *_dns_client_work(void *arg)
if (sleep_time <= 0) {
sleep_time = 0;
}
int cnt = sleep_time / sleep;
msec -= cnt;
expect_time -= cnt * sleep;
sleep_time -= cnt * sleep;
}
if (now >= expect_time) {
msec++;
if (last != now) {
_dns_client_period_run();
_dns_client_period_run(msec);
}
sleep_time = sleep - (now - expect_time);
@@ -3873,19 +3917,21 @@ static void *_dns_client_work(void *arg)
sleep_time = 0;
expect_time = now;
}
/* When client is idle, the sleep time is 1000ms, to reduce CPU usage */
pthread_mutex_lock(&client.domain_map_lock);
if (list_empty(&client.dns_request_list)) {
int cnt = 10 - (msec % 10) - 1;
sleep_time += sleep * cnt;
msec += cnt;
/* sleep to next second */
expect_time += sleep * cnt;
}
pthread_mutex_unlock(&client.domain_map_lock);
expect_time += sleep;
}
last = now;
pthread_mutex_lock(&client.domain_map_lock);
if (list_empty(&client.dns_request_list) && atomic_read(&client.run_period) == 0) {
pthread_cond_wait(&client.run_cond, &client.domain_map_lock);
expect_time = get_tick_count();
pthread_mutex_unlock(&client.domain_map_lock);
continue;
}
pthread_mutex_unlock(&client.domain_map_lock);
num = epoll_wait(client.epoll_fd, events, DNS_MAX_EVENTS, sleep_time);
if (num < 0) {
usleep(100000);
@@ -3895,6 +3941,11 @@ static void *_dns_client_work(void *arg)
for (i = 0; i < num; i++) {
struct epoll_event *event = &events[i];
struct dns_server_info *server_info = (struct dns_server_info *)event->data.ptr;
if (event->data.fd == client.fd_wakeup) {
_dns_client_clear_wakeup_event();
continue;
}
if (server_info == NULL) {
tlog(TLOG_WARN, "server info is invalid.");
continue;
@@ -3948,10 +3999,71 @@ int dns_client_set_ecs(char *ip, int subnet)
return 0;
}
static int _dns_client_create_wakeup_event(void)
{
int fd_wakeup = -1;
fd_wakeup = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (fd_wakeup < 0) {
tlog(TLOG_ERROR, "create eventfd failed, %s\n", strerror(errno));
goto errout;
}
struct epoll_event event;
memset(&event, 0, sizeof(event));
event.events = EPOLLIN;
event.data.fd = fd_wakeup;
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd_wakeup, &event) < 0) {
tlog(TLOG_ERROR, "add eventfd to epoll failed, %s\n", strerror(errno));
goto errout;
}
return fd_wakeup;
errout:
if (fd_wakeup > 0) {
close(fd_wakeup);
}
return -1;
}
static void _dns_client_close_wakeup_event(void)
{
if (client.fd_wakeup > 0) {
close(client.fd_wakeup);
client.fd_wakeup = -1;
}
}
static void _dns_client_clear_wakeup_event(void)
{
uint64_t val = 0;
int unused __attribute__((unused));
if (client.fd_wakeup <= 0) {
return;
}
unused = read(client.fd_wakeup, &val, sizeof(val));
}
static void _dns_client_do_wakeup_event(void)
{
uint64_t val = 1;
int unused __attribute__((unused));
if (client.fd_wakeup <= 0) {
return;
}
unused = write(client.fd_wakeup, &val, sizeof(val));
}
int dns_client_init(void)
{
pthread_attr_t attr;
int epollfd = -1;
int fd_wakeup = -1;
int ret = 0;
if (client.epoll_fd > 0) {
@@ -3979,8 +4091,6 @@ int dns_client_init(void)
hash_init(client.group);
INIT_LIST_HEAD(&client.dns_request_list);
pthread_cond_init(&client.run_cond, NULL);
if (dns_client_add_group(DNS_SERVER_GROUP_DEFAULT) != 0) {
tlog(TLOG_ERROR, "add default server group failed.");
goto errout;
@@ -3997,6 +4107,14 @@ int dns_client_init(void)
goto errout;
}
fd_wakeup = _dns_client_create_wakeup_event();
if (fd_wakeup < 0) {
tlog(TLOG_ERROR, "create wakeup event failed, %s\n", strerror(errno));
goto errout;
}
client.fd_wakeup = fd_wakeup;
return 0;
errout:
if (client.tid) {
@@ -4006,13 +4124,16 @@ errout:
client.tid = 0;
}
if (epollfd) {
if (epollfd > 0) {
close(epollfd);
}
if (fd_wakeup > 0) {
close(fd_wakeup);
}
pthread_mutex_destroy(&client.server_list_lock);
pthread_mutex_destroy(&client.domain_map_lock);
pthread_cond_destroy(&client.run_cond);
return -1;
}
@@ -4022,14 +4143,13 @@ void dns_client_exit(void)
if (client.tid) {
void *ret = NULL;
atomic_set(&client.run, 0);
pthread_mutex_lock(&client.domain_map_lock);
pthread_cond_signal(&client.run_cond);
pthread_mutex_unlock(&client.domain_map_lock);
_dns_client_do_wakeup_event();
pthread_join(client.tid, &ret);
client.tid = 0;
}
/* free all resources */
_dns_client_close_wakeup_event();
_dns_client_remove_all_pending_servers();
_dns_client_server_remove_all();
_dns_client_query_remove_all();
@@ -4037,7 +4157,6 @@ void dns_client_exit(void)
pthread_mutex_destroy(&client.server_list_lock);
pthread_mutex_destroy(&client.domain_map_lock);
pthread_cond_destroy(&client.run_cond);
if (client.ssl_ctx) {
SSL_CTX_free(client.ssl_ctx);
client.ssl_ctx = NULL;

View File

@@ -113,6 +113,7 @@ struct client_dns_server_flags {
unsigned int server_flag;
unsigned int result_flag;
long long set_mark;
int drop_packet_latency_ms;
char proxyname[DNS_MAX_CNAME_LEN];
union {
struct client_dns_server_flag_udp udp;

View File

@@ -61,6 +61,9 @@ static time_t dns_conf_dnsmasq_lease_file_time;
struct dns_hosts_table dns_hosts_table;
int dns_hosts_record_num;
/* DNS64 */
struct dns_dns64 dns_conf_dns_dns64;
/* server ip/port */
struct dns_bind_ip dns_conf_bind_ip[DNS_MAX_BIND_IP];
int dns_conf_bind_ip_num = 0;
@@ -129,7 +132,7 @@ struct dns_conf_address_rule dns_conf_address_rule;
/* dual-stack selection */
int dns_conf_dualstack_ip_selection = 1;
int dns_conf_dualstack_ip_allow_force_AAAA;
int dns_conf_dualstack_ip_selection_threshold = 15;
int dns_conf_dualstack_ip_selection_threshold = 10;
/* TTL */
int dns_conf_rr_ttl;
@@ -140,7 +143,9 @@ int dns_conf_local_ttl;
int dns_conf_force_AAAA_SOA;
int dns_conf_force_no_cname;
int dns_conf_ipset_timeout_enable;
struct dns_ipset_names dns_conf_ipset_no_speed;
int dns_conf_nftset_timeout_enable;
struct dns_nftset_names dns_conf_nftset_no_speed;
int dns_conf_nftset_debug_enable;
char dns_conf_user[DNS_CONF_USERNAME_LEN];
@@ -189,6 +194,12 @@ static void *_new_dns_rule(enum domain_rule domain_rule)
case DOMAIN_RULE_CHECKSPEED:
size = sizeof(struct dns_domain_check_orders);
break;
case DOMAIN_RULE_CNAME:
size = sizeof(struct dns_cname_rule);
break;
case DOMAIN_RULE_TTL:
size = sizeof(struct dns_ttl_rule);
break;
default:
return NULL;
}
@@ -451,6 +462,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
unsigned int result_flag = 0;
unsigned int server_flag = 0;
unsigned char *spki = NULL;
int drop_packet_latency_ms = 0;
int ttl = 0;
/* clang-format off */
@@ -461,6 +473,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
/* experimental feature */
{"check-edns", no_argument, NULL, 'e'}, /* check edns */
#endif
{"drop-packet-latency", required_argument, NULL, 'D'},
{"spki-pin", required_argument, NULL, 'p'}, /* check SPKI pin */
{"host-name", required_argument, NULL, 'h'}, /* host name */
{"http-host", required_argument, NULL, 'H'}, /* http host */
@@ -492,6 +505,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
server->tls_host_verify[0] = '\0';
server->proxyname[0] = '\0';
server->set_mark = -1;
server->drop_packet_latency_ms = drop_packet_latency_ms;
if (parse_uri(ip, scheme, server->server, &port, server->path) != 0) {
return -1;
@@ -561,6 +575,10 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
safe_strncpy(server->httphost, optarg, DNS_MAX_CNAME_LEN);
break;
}
case 'D': {
drop_packet_latency_ms = atoi(optarg);
break;
}
case 'E': {
server_flag |= SERVER_FLAG_EXCLUDE_DEFAULT;
break;
@@ -607,6 +625,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
server->result_flag = result_flag;
server->server_flag = server_flag;
server->ttl = ttl;
server->drop_packet_latency_ms = drop_packet_latency_ms;
dns_conf_server_num++;
tlog(TLOG_DEBUG, "add server %s, flag: %X, ttl: %d", ip, result_flag, ttl);
@@ -1076,6 +1095,78 @@ errout:
return 0;
}
static int _config_ipset_no_speed(void *data, int argc, char *argv[])
{
char *ipsetname = argv[1];
char *copied_name = NULL;
const char *ipset = NULL;
struct dns_ipset_rule *ipset_rule_array[2] = {NULL, NULL};
char *ipset_rule_enable_array[2] = {NULL, NULL};
int ipset_num = 0;
if (argc <= 1) {
goto errout;
}
copied_name = strdup(ipsetname);
if (copied_name == NULL) {
goto errout;
}
for (char *tok = strtok(copied_name, ","); tok && ipset_num <= 2; tok = strtok(NULL, ",")) {
if (tok[0] == '#') {
if (strncmp(tok, "#6:", 3U) == 0) {
ipset_rule_array[ipset_num] = &dns_conf_ipset_no_speed.ipv6;
ipset_rule_enable_array[ipset_num] = &dns_conf_ipset_no_speed.ipv6_enable;
ipset_num++;
} else if (strncmp(tok, "#4:", 3U) == 0) {
ipset_rule_array[ipset_num] = &dns_conf_ipset_no_speed.ipv4;
ipset_rule_enable_array[ipset_num] = &dns_conf_ipset_no_speed.ipv4_enable;
ipset_num++;
} else {
goto errout;
}
tok += 3;
}
if (ipset_num == 0) {
ipset_rule_array[1] = &dns_conf_ipset_no_speed.ipv6;
ipset_rule_enable_array[1] = &dns_conf_ipset_no_speed.ipv6_enable;
ipset_rule_array[0] = &dns_conf_ipset_no_speed.ipv4;
ipset_rule_enable_array[0] = &dns_conf_ipset_no_speed.ipv4_enable;
ipset_num = 2;
}
if (strncmp(tok, "-", 1) == 0) {
continue;
}
/* new ipset domain */
ipset = _dns_conf_get_ipset(tok);
if (ipset == NULL) {
goto errout;
}
for (int i = 0; i < ipset_num; i++) {
ipset_rule_array[i]->ipsetname = ipset;
*ipset_rule_enable_array[i] = 1;
}
ipset_num = 0;
}
free(copied_name);
return 0;
errout:
if (copied_name) {
free(copied_name);
}
tlog(TLOG_ERROR, "add ipset-no-speed %s failed", ipsetname);
return 0;
}
static void _config_nftset_table_destroy(void)
{
struct dns_nftset_name *nftset = NULL;
@@ -1187,7 +1278,7 @@ static int _conf_domain_rule_nftset(char *domain, const char *nftsetname)
goto errout;
}
/* new ipset domain */
/* new nftset domain */
nftset = _dns_conf_get_nftable(family, tablename, setname);
if (nftset == NULL) {
goto errout;
@@ -1244,6 +1335,105 @@ errout:
return 0;
}
static int _config_nftset_no_speed(void *data, int argc, char *argv[])
{
const struct dns_nftset_name *nftset = NULL;
char *copied_name = NULL;
char *nftsetname = argv[1];
int nftset_num = 0;
char *setname = NULL;
char *tablename = NULL;
char *family = NULL;
struct dns_nftset_rule *nftset_rule_array[2] = {NULL, NULL};
char *nftset_rule_enable_array[2] = {NULL, NULL};
if (argc <= 1) {
goto errout;
}
copied_name = strdup(nftsetname);
if (copied_name == NULL) {
goto errout;
}
for (char *tok = strtok(copied_name, ","); tok && nftset_num <=2 ; tok = strtok(NULL, ",")) {
char *saveptr = NULL;
char *tok_set = NULL;
if (strncmp(tok, "#4:", 3U) == 0) {
dns_conf_nftset_no_speed.ip_enable = 1;
nftset_rule_array[nftset_num] = &dns_conf_nftset_no_speed.ip;
nftset_rule_enable_array[nftset_num] = &dns_conf_nftset_no_speed.ip_enable;
nftset_num++;
} else if (strncmp(tok, "#6:", 3U) == 0) {
nftset_rule_enable_array[nftset_num] = &dns_conf_nftset_no_speed.ip6_enable;
nftset_rule_array[nftset_num] = &dns_conf_nftset_no_speed.ip6;
nftset_num++;
} else if (strncmp(tok, "-", 2U) == 0) {
continue;
continue;
} else {
goto errout;
}
tok_set = tok + 3;
if (nftset_num == 0) {
nftset_rule_array[0] = &dns_conf_nftset_no_speed.ip;
nftset_rule_enable_array[0] = &dns_conf_nftset_no_speed.ip_enable;
nftset_rule_array[1] = &dns_conf_nftset_no_speed.ip6;
nftset_rule_enable_array[1] = &dns_conf_nftset_no_speed.ip6_enable;
nftset_num = 2;
}
if (strncmp(tok_set, "-", 2U) == 0) {
continue;
}
family = strtok_r(tok_set, "#", &saveptr);
if (family == NULL) {
goto errout;
}
tablename = strtok_r(NULL, "#", &saveptr);
if (tablename == NULL) {
goto errout;
}
setname = strtok_r(NULL, "#", &saveptr);
if (setname == NULL) {
goto errout;
}
/* new nftset domain */
nftset = _dns_conf_get_nftable(family, tablename, setname);
if (nftset == NULL) {
goto errout;
}
for (int i = 0; i < nftset_num; i++) {
nftset_rule_array[i]->familyname = nftset->nftfamilyname;
nftset_rule_array[i]->nfttablename = nftset->nfttablename;
nftset_rule_array[i]->nftsetname = nftset->nftsetname;
*nftset_rule_enable_array[i] = 1;
}
nftset_num = 0;
}
goto clear;
errout:
tlog(TLOG_ERROR, "add nftset %s failed", nftsetname);
clear:
if (copied_name) {
free(copied_name);
}
return 0;
}
static int _conf_domain_rule_address(char *domain, const char *domain_address)
{
struct dns_rule_address_IPV4 *address_ipv4 = NULL;
@@ -1374,6 +1564,64 @@ errout:
return 0;
}
static int _conf_domain_rule_cname(const char *domain, const char *cname)
{
struct dns_cname_rule *cname_rule = NULL;
enum domain_rule type = DOMAIN_RULE_CNAME;
cname_rule = _new_dns_rule(type);
if (cname_rule == NULL) {
goto errout;
}
/* ignore this domain */
if (*cname == '-') {
if (_config_domain_rule_flag_set(domain, DOMAIN_FLAG_CNAME_IGN, 0) != 0) {
goto errout;
}
return 0;
}
safe_strncpy(cname_rule->cname, cname, DNS_MAX_CONF_CNAME_LEN);
if (_config_domain_rule_add(domain, type, cname_rule) != 0) {
goto errout;
}
_dns_rule_put(&cname_rule->head);
cname_rule = NULL;
return 0;
errout:
tlog(TLOG_ERROR, "add cname %s:%s failed", domain, cname);
if (cname_rule) {
_dns_rule_put(&cname_rule->head);
}
return 0;
}
static int _config_cname(void *data, int argc, char *argv[])
{
char *value = argv[1];
char domain[DNS_MAX_CONF_CNAME_LEN];
if (argc <= 1) {
goto errout;
}
if (_get_domain(value, domain, DNS_MAX_CONF_CNAME_LEN, &value) != 0) {
goto errout;
}
return _conf_domain_rule_cname(domain, value);
errout:
tlog(TLOG_ERROR, "add cname %s:%s failed", domain, value);
return 0;
}
static void _config_speed_check_mode_clear(struct dns_domain_check_orders *check_orders)
{
memset(check_orders->orders, 0, sizeof(check_orders->orders));
@@ -1453,6 +1701,43 @@ static int _config_speed_check_mode(void *data, int argc, char *argv[])
return _config_speed_check_mode_parser(&dns_conf_check_orders, mode);
}
static int _config_dns64(void *data, int argc, char *argv[])
{
prefix_t prefix;
char *subnet = NULL;
const char *errmsg = NULL;
void *p = NULL;
if (argc <= 1) {
return -1;
}
subnet = argv[1];
p = prefix_pton(subnet, -1, &prefix, &errmsg);
if (p == NULL) {
goto errout;
}
if (prefix.family != AF_INET6) {
tlog(TLOG_ERROR, "dns64 subnet %s is not ipv6", subnet);
goto errout;
}
if (prefix.bitlen <= 0 || prefix.bitlen > 96) {
tlog(TLOG_ERROR, "dns64 subnet %s is not valid", subnet);
goto errout;
}
memcpy(&dns_conf_dns_dns64.prefix, &prefix.add.sin6.s6_addr, sizeof(dns_conf_dns_dns64.prefix));
dns_conf_dns_dns64.prefix_len = prefix.bitlen;
return 0;
errout:
return -1;
}
static int _config_bind_ip(int argc, char *argv[], DNS_BIND_TYPE type)
{
int index = dns_conf_bind_ip_num;
@@ -2129,6 +2414,39 @@ errout:
return -1;
}
static int _conf_domain_rule_rr_ttl(const char *domain, int ttl, int ttl_min, int ttl_max)
{
struct dns_ttl_rule *rr_ttl = NULL;
if (ttl < 0 || ttl_min < 0 || ttl_max < 0) {
tlog(TLOG_ERROR, "invalid ttl value.");
goto errout;
}
rr_ttl = _new_dns_rule(DOMAIN_RULE_TTL);
if (rr_ttl == NULL) {
goto errout;
}
rr_ttl->ttl = ttl;
rr_ttl->ttl_min = ttl_min;
rr_ttl->ttl_max = ttl_max;
if (_config_domain_rule_add(domain, DOMAIN_RULE_TTL, rr_ttl) != 0) {
goto errout;
}
_dns_rule_put(&rr_ttl->head);
return 0;
errout:
if (rr_ttl != NULL) {
_dns_rule_put(&rr_ttl->head);
}
return -1;
}
static int _conf_domain_rule_no_serve_expired(const char *domain)
{
return _config_domain_rule_flag_set(domain, DOMAIN_FLAG_NO_SERVE_EXPIRED, 0);
@@ -2144,6 +2462,9 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
int opt = 0;
char domain[DNS_MAX_CONF_CNAME_LEN];
char *value = argv[1];
int rr_ttl = 0;
int rr_ttl_min = 0;
int rr_ttl_max = 0;
/* clang-format off */
static struct option long_options[] = {
@@ -2153,6 +2474,10 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
{"nftset", required_argument, NULL, 't'},
{"nameserver", required_argument, NULL, 'n'},
{"dualstack-ip-selection", required_argument, NULL, 'd'},
{"cname", required_argument, NULL, 'A'},
{"rr-ttl", required_argument, NULL, 251},
{"rr-ttl-min", required_argument, NULL, 252},
{"rr-ttl-max", required_argument, NULL, 253},
{"no-serve-expired", no_argument, NULL, 254},
{"delete", no_argument, NULL, 255},
{NULL, no_argument, NULL, 0}
@@ -2171,7 +2496,7 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
/* process extra options */
optind = 1;
while (1) {
opt = getopt_long_only(argc, argv, "c:a:p:t:n:d:", long_options, NULL);
opt = getopt_long_only(argc, argv, "c:a:p:t:n:d:A:", long_options, NULL);
if (opt == -1) {
break;
}
@@ -2229,6 +2554,16 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
break;
}
case 'A': {
const char *cname = optarg;
if (_conf_domain_rule_cname(domain, cname) != 0) {
tlog(TLOG_ERROR, "add cname rule failed.");
goto errout;
}
break;
}
case 'd': {
const char *yesno = optarg;
if (_conf_domain_rule_dualstack_selection(domain, yesno) != 0) {
@@ -2251,6 +2586,18 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
break;
}
case 251: {
rr_ttl = atoi(optarg);
break;
}
case 252: {
rr_ttl_min = atoi(optarg);
break;
}
case 253: {
rr_ttl_max = atoi(optarg);
break;
}
case 254: {
if (_conf_domain_rule_no_serve_expired(domain) != 0) {
tlog(TLOG_ERROR, "set no-serve-expired rule failed.");
@@ -2272,6 +2619,13 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
}
}
if (rr_ttl > 0 || rr_ttl_min > 0 || rr_ttl_max > 0) {
if (_conf_domain_rule_rr_ttl(domain, rr_ttl, rr_ttl_min, rr_ttl_max) != 0) {
tlog(TLOG_ERROR, "set rr-ttl rule failed.");
goto errout;
}
}
return 0;
errout:
return -1;
@@ -2693,12 +3047,15 @@ static struct config_item _config_item[] = {
CONF_CUSTOM("server-https", _config_server_https, NULL),
CONF_CUSTOM("nameserver", _config_nameserver, NULL),
CONF_CUSTOM("address", _config_address, NULL),
CONF_CUSTOM("cname", _config_cname, NULL),
CONF_CUSTOM("proxy-server", _config_proxy_server, NULL),
CONF_YESNO("ipset-timeout", &dns_conf_ipset_timeout_enable),
CONF_CUSTOM("ipset", _config_ipset, NULL),
CONF_CUSTOM("ipset-no-speed", _config_ipset_no_speed, NULL),
CONF_YESNO("nftset-timeout", &dns_conf_nftset_timeout_enable),
CONF_YESNO("nftset-debug", &dns_conf_nftset_debug_enable),
CONF_CUSTOM("nftset", _config_nftset, NULL),
CONF_CUSTOM("nftset-no-speed", _config_nftset_no_speed, NULL),
CONF_CUSTOM("speed-check-mode", _config_speed_check_mode, NULL),
CONF_INT("tcp-idle-time", &dns_conf_tcp_idle_time, 0, 3600),
CONF_INT("cache-size", &dns_conf_cachesize, 0, CONF_INT_MAX),
@@ -2712,6 +3069,7 @@ static struct config_item _config_item[] = {
CONF_YESNO("dualstack-ip-selection", &dns_conf_dualstack_ip_selection),
CONF_YESNO("dualstack-ip-allow-force-AAAA", &dns_conf_dualstack_ip_allow_force_AAAA),
CONF_INT("dualstack-ip-selection-threshold", &dns_conf_dualstack_ip_selection_threshold, 0, 1000),
CONF_CUSTOM("dns64", _config_dns64, NULL),
CONF_CUSTOM("log-level", _config_log_level, NULL),
CONF_STRING("log-file", (char *)dns_conf_log_file, DNS_MAX_PATH),
CONF_SIZE("log-size", &dns_conf_log_size, 0, 1024 * 1024 * 1024),
@@ -2782,7 +3140,7 @@ int config_additional_file(void *data, int argc, char *argv[])
conf_file = argv[1];
if (conf_file[0] != '/') {
safe_strncpy(file_path_dir, conf_get_conf_file(), DNS_MAX_PATH);
dirname(file_path_dir);
dir_name(file_path_dir);
if (strncmp(file_path_dir, conf_get_conf_file(), sizeof(file_path_dir)) == 0) {
if (snprintf(file_path, DNS_MAX_PATH, "%s", conf_file) < 0) {
return -1;
@@ -2925,10 +3283,6 @@ static int _dns_conf_load_post(void)
dns_conf_rr_ttl_max = dns_conf_rr_ttl_min;
}
if (dns_conf_local_ttl == 0) {
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));
}

View File

@@ -74,6 +74,8 @@ enum domain_rule {
DOMAIN_RULE_NFTSET_IP6,
DOMAIN_RULE_NAMESERVER,
DOMAIN_RULE_CHECKSPEED,
DOMAIN_RULE_CNAME,
DOMAIN_RULE_TTL,
DOMAIN_RULE_MAX,
};
@@ -83,10 +85,12 @@ typedef enum {
DNS_BIND_TYPE_TLS,
} DNS_BIND_TYPE;
#define DOMAIN_CHECK_NONE 0
#define DOMAIN_CHECK_ICMP 1
#define DOMAIN_CHECK_TCP 2
#define DOMAIN_CHECK_NUM 3
typedef enum {
DOMAIN_CHECK_NONE = 0,
DOMAIN_CHECK_ICMP = 1,
DOMAIN_CHECK_TCP = 2,
DOMAIN_CHECK_NUM = 3,
} DOMAIN_CHECK_TYPE;
#define DOMAIN_FLAG_ADDR_SOA (1 << 0)
#define DOMAIN_FLAG_ADDR_IPV4_SOA (1 << 1)
@@ -104,6 +108,7 @@ typedef enum {
#define DOMAIN_FLAG_NFTSET_IP_IGN (1 << 13)
#define DOMAIN_FLAG_NFTSET_IP6_IGN (1 << 14)
#define DOMAIN_FLAG_NO_SERVE_EXPIRED (1 << 15)
#define DOMAIN_FLAG_CNAME_IGN (1 << 16)
#define SERVER_FLAG_EXCLUDE_DEFAULT (1 << 0)
@@ -116,6 +121,7 @@ typedef enum {
#define BIND_FLAG_NO_CACHE (1 << 6)
#define BIND_FLAG_NO_DUALSTACK_SELECTION (1 << 7)
#define BIND_FLAG_FORCE_AAAA_SOA (1 << 8)
#define BIND_FLAG_NO_RULE_CNAME (1 << 9)
struct dns_rule {
atomic_t refcnt;
@@ -148,6 +154,26 @@ struct dns_ipset_rule {
const char *ipsetname;
};
struct dns_ipset_names {
char ipv4_enable;
char ipv6_enable;
struct dns_ipset_rule ipv4;
struct dns_ipset_rule ipv6;
};
extern struct dns_ipset_names dns_conf_ipset_no_speed;
struct dns_cname_rule {
struct dns_rule head;
char cname[DNS_MAX_CNAME_LEN];
};
struct dns_ttl_rule {
struct dns_rule head;
int ttl;
int ttl_max;
int ttl_min;
};
struct dns_nftset_name {
struct hlist_node node;
char nftfamilyname[DNS_MAX_NFTSET_FAMILYLEN];
@@ -162,6 +188,16 @@ struct dns_nftset_rule {
const char *nftsetname;
};
struct dns_nftset_names {
char inet_enable;
char ip_enable;
char ip6_enable;
struct dns_nftset_rule inet;
struct dns_nftset_rule ip;
struct dns_nftset_rule ip6;
};
extern struct dns_nftset_names dns_conf_nftset_no_speed;
struct dns_domain_rule {
struct dns_rule head;
struct dns_rule *rules[DOMAIN_RULE_MAX];
@@ -181,7 +217,7 @@ struct dns_server_groups {
};
struct dns_domain_check_order {
char type;
DOMAIN_CHECK_TYPE type;
unsigned short tcp_port;
};
@@ -248,6 +284,7 @@ struct dns_servers {
int ttl;
dns_server_type_t type;
long long set_mark;
unsigned int drop_packet_latency_ms;
char skip_check_cert;
char spki[DNS_MAX_SPKI_LEN];
char hostname[DNS_MAX_CNAME_LEN];
@@ -359,6 +396,13 @@ struct dns_set_rule_flags_callback_args {
int is_clear_flag;
};
struct dns_dns64 {
unsigned char prefix[DNS_RR_AAAA_LEN];
uint32_t prefix_len;
};
extern struct dns_dns64 dns_conf_dns_dns64;
extern struct dns_bind_ip dns_conf_bind_ip[DNS_MAX_BIND_IP];
extern int dns_conf_bind_ip_num;

File diff suppressed because it is too large Load Diff

View File

@@ -336,7 +336,8 @@ static struct addrinfo *_fast_ping_getaddr(const char *host, const char *port, i
hints.ai_protocol = protocol;
errcode = getaddrinfo(host, port, &hints, &result);
if (errcode != 0) {
tlog(TLOG_ERROR, "get addr info failed. host:%s, port: %s, error %s\n", host, port, gai_strerror(errcode));
tlog(TLOG_ERROR, "get addr info failed. host:%s, port: %s, error %s\n", host != NULL ? host : "",
port != NULL ? port : "", gai_strerror(errcode));
goto errout;
}

View File

@@ -32,6 +32,16 @@ const char *conf_get_conf_file(void)
return current_conf_file;
}
static char *get_dir_name(char *path)
{
if (strstr(path, "/") == NULL) {
strncpy(path, "./", PATH_MAX);
return path;
}
return dirname(path);
}
const char *conf_get_conf_fullpath(const char *path, char *fullpath, size_t path_len)
{
char file_path_dir[PATH_MAX];
@@ -47,7 +57,7 @@ const char *conf_get_conf_fullpath(const char *path, char *fullpath, size_t path
strncpy(file_path_dir, conf_get_conf_file(), PATH_MAX - 1);
file_path_dir[PATH_MAX - 1] = 0;
dirname(file_path_dir);
get_dir_name(file_path_dir);
if (file_path_dir[0] == '\0') {
strncpy(fullpath, path, path_len);
return fullpath;

View File

@@ -269,6 +269,7 @@ static int _smartdns_add_servers(void)
flags.server_flag = dns_conf_servers[i].server_flag;
flags.result_flag = dns_conf_servers[i].result_flag;
flags.set_mark = dns_conf_servers[i].set_mark;
flags.drop_packet_latency_ms = dns_conf_servers[i].drop_packet_latency_ms;
safe_strncpy(flags.proxyname, dns_conf_servers[i].proxyname, sizeof(flags.proxyname));
ret = dns_client_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type,
&flags);
@@ -542,7 +543,7 @@ static int _smartdns_create_logdir(void)
int gid = 0;
char logdir[PATH_MAX] = {0};
safe_strncpy(logdir, _smartdns_log_path(), PATH_MAX);
dirname(logdir);
dir_name(logdir);
if (access(logdir, F_OK) == 0) {
return 0;

View File

@@ -110,6 +110,7 @@ struct tlog {
tlog_log_output_func output_func;
struct tlog_log *wait_on_log;
int is_wait;
char gzip_cmd[PATH_MAX];
};
struct tlog_segment_log_head {
@@ -520,7 +521,7 @@ static int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, v
return -1;
}
if (unlikely(log->logcount <= 0 && log->logscreen == 0) ) {
if (unlikely(log->logcount <= 0 && log->logscreen == 0)) {
return 0;
}
@@ -1018,7 +1019,6 @@ errout:
static int _tlog_archive_log_compressed(struct tlog_log *log)
{
char gzip_file[TLOG_BUFF_LEN];
char gzip_cmd[PATH_MAX * 2];
char log_file[TLOG_BUFF_LEN];
char pending_file[TLOG_BUFF_LEN];
@@ -1046,12 +1046,11 @@ static int _tlog_archive_log_compressed(struct tlog_log *log)
}
/* start gzip process to compress log file */
snprintf(gzip_cmd, sizeof(gzip_cmd), "gzip -1 %s", pending_file);
if (log->zip_pid <= 0) {
int pid = vfork();
if (pid == 0) {
_tlog_close_all_fd();
execl("/bin/sh", "sh", "-c", gzip_cmd, NULL);
execl(tlog.gzip_cmd, tlog.gzip_cmd, "-1", pending_file, NULL);
_exit(1);
} else if (pid < 0) {
goto errout;
@@ -1363,12 +1362,26 @@ static struct tlog_log *_tlog_wait_log_locked(struct tlog_log *last_log)
int ret = 0;
struct timespec tm;
struct tlog_log *log = NULL;
struct tlog_log *next = NULL;
int need_wait_pid = 0;
for (next = tlog.log; next != NULL; next = next->next) {
if (next->zip_pid > 0) {
need_wait_pid = 1;
break;
}
}
clock_gettime(CLOCK_REALTIME, &tm);
tm.tv_sec += 2;
tlog.is_wait = 1;
tlog.wait_on_log = last_log;
ret = pthread_cond_timedwait(&tlog.cond, &tlog.lock, &tm);
if (need_wait_pid != 0) {
ret = pthread_cond_timedwait(&tlog.cond, &tlog.lock, &tm);
} else {
ret = pthread_cond_wait(&tlog.cond, &tlog.lock);
}
tlog.is_wait = 0;
tlog.wait_on_log = NULL;
errno = ret;
@@ -1676,6 +1689,15 @@ int tlog_setlevel(tlog_level level)
return 0;
}
int tlog_log_enabled(tlog_level level)
{
if (level >= TLOG_END) {
return 0;
}
return (tlog_set_level >= level) ? 1 : 0;
}
tlog_level tlog_getlevel(void)
{
return tlog_set_level;
@@ -1686,6 +1708,35 @@ void tlog_set_logfile(const char *logfile)
tlog_rename_logfile(tlog.root, logfile);
}
static void _tlog_get_gzip_cmd_path(void)
{
char *copy_path = NULL;
char gzip_cmd_path[PATH_MAX];
const char *env_path = getenv("PATH");
char *save_ptr = NULL;
if (env_path == NULL) {
env_path = "/bin:/usr/bin:/usr/local/bin";
}
copy_path = strdup(env_path);
if (copy_path == NULL) {
return;
}
for (char *tok = strtok_r(copy_path, ":", &save_ptr); tok; tok = strtok_r(NULL, ":", &save_ptr)) {
snprintf(gzip_cmd_path, sizeof(gzip_cmd_path), "%s/gzip", tok);
if (access(gzip_cmd_path, X_OK) != 0) {
continue;
}
snprintf(tlog.gzip_cmd, sizeof(tlog.gzip_cmd), "%s", gzip_cmd_path);
break;
}
free(copy_path);
}
tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag)
{
struct tlog_log *log = NULL;
@@ -1726,6 +1777,10 @@ tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int bu
log->file_perm = S_IRUSR | S_IWUSR | S_IRGRP;
log->archive_perm = S_IRUSR | S_IRGRP;
if (log->nocompress == 0 && tlog.gzip_cmd[0] == '\0') {
log->nocompress = 1;
}
tlog_rename_logfile(log, logfile);
if (log->nocompress) {
strncpy(log->suffix, TLOG_SUFFIX_LOG, sizeof(log->suffix));
@@ -1859,6 +1914,7 @@ int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int buffsize
memset(&tlog, 0, sizeof(tlog));
tlog.is_wait = 0;
_tlog_get_gzip_cmd_path();
pthread_attr_init(&attr);
pthread_cond_init(&tlog.cond, NULL);
pthread_mutex_init(&tlog.lock, NULL);
@@ -1871,6 +1927,10 @@ int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int buffsize
}
tlog_reg_output_func(log, _tlog_root_write_log);
if ((flag & TLOG_NOCOMPRESS) == 0 && tlog.gzip_cmd[0] == '\0') {
fprintf(stderr, "can not find gzip command, disable compress.\n");
}
tlog.root = log;
ret = pthread_create(&tlog.tid, &attr, _tlog_work, NULL);
if (ret != 0) {

View File

@@ -79,9 +79,9 @@ level: Current log Levels
format: Log formats
*/
#ifndef BASE_FILE_NAME
#define BASE_FILE_NAME \
(__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \
: __FILE__)
#define BASE_FILE_NAME \
(__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \
: __FILE__)
#endif
#define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, NULL, format, ##__VA_ARGS__)
@@ -95,6 +95,9 @@ extern int tlog_write_log(char *buff, int bufflen);
/* set log level */
extern int tlog_setlevel(tlog_level level);
/* is log level enabled*/
extern int tlog_log_enabled(tlog_level level);
/* get log level */
extern tlog_level tlog_getlevel(void);
@@ -137,7 +140,7 @@ read _tlog_format for example.
typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_loginfo *info, void *userptr, const char *format, va_list ap);
extern int tlog_reg_format_func(tlog_format_func func);
/* register log output callback
/* register log output callback
Note: info is invalid when flag TLOG_SEGMENT is not set.
*/
typedef int (*tlog_log_output_func)(struct tlog_loginfo *info, const char *buff, int bufflen, void *private_data);
@@ -213,7 +216,7 @@ file: log file permission, default is 640
archive: archive file permission, default is 440
*/
extern void tlog_set_permission(struct tlog_log *log, mode_t file, mode_t archive);
extern void tlog_set_permission(struct tlog_log *log, mode_t file, mode_t archive);
#ifdef __cplusplus
class Tlog {

View File

@@ -29,6 +29,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libgen.h>
#include <linux/capability.h>
#include <linux/limits.h>
#include <linux/netlink.h>
@@ -109,6 +110,16 @@ unsigned long get_tick_count(void)
return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
}
char *dir_name(char *path)
{
if (strstr(path, "/") == NULL) {
safe_strncpy(path, "./", PATH_MAX);
return path;
}
return dirname(path);
}
char *get_host_by_addr(char *host, int maxsize, struct sockaddr *addr)
{
struct sockaddr_storage *addr_store = (struct sockaddr_storage *)addr;

View File

@@ -55,6 +55,8 @@ void bug_ext(const char *file, int line, const char *func, const char *errfmt, .
unsigned long get_tick_count(void);
char *dir_name(char *path);
char *get_host_by_addr(char *host, int maxsize, struct sockaddr *addr);
int getaddr_by_host(const char *host, struct sockaddr *addr, socklen_t *addr_len);