Compare commits

...

9 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
10 changed files with 270 additions and 94 deletions

View File

@@ -172,6 +172,8 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
| OpenWrtARM | smartdns.1.yyyy.MM.dd-REL.arm-openwrt-all.ipk | ARM 小端架构的 OpenWrt 系统 | | 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.ipk | OpenWrt 管理界面 |
| OpenWrt LuCI | luci-app-smartdns.1.yyyy.MM.dd-REL.all-luci-compat-all.ipk | OpenWrt 管理界面、OpenWrt 18.xx 及之前版本 | | 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)。**
@@ -181,8 +183,6 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
- 静态编译的软件包未强制判断 CPU 架构,安装不正确的软件包将会导致服务无法启动,请确保正确安装对应的版本。 - 静态编译的软件包未强制判断 CPU 架构,安装不正确的软件包将会导致服务无法启动,请确保正确安装对应的版本。
- MacOSWindows可获取Rust语言实现的Smartdns: [SmartDNS-rs](https://github.com/mokeyish/smartdns-rs)。
## 安装和使用 ## 安装和使用
### 标准 Linux 系统 / 树莓派 ### 标准 Linux 系统 / 树莓派
@@ -612,7 +612,7 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
| 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:- <br />ipset /www.example.com/dns | | 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 | | ipset-timeout | 设置 ipset 超时功能启用 | no | [yes\|no] | ipset-timeout yes |
| ipset-no-speed | 当测速失败时将域名结果设置到ipset集合中 | 无 | ipset \| #[4\|6]:ipset | ipset-no-speed #4:ipset4,#6:ipse6 <br /> ipset-no-speed ipset| | 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 | 域名 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-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-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|
@@ -630,8 +630,9 @@ entware|ipkg update<br />ipkg install smartdns|软件源路径:<https://bin.en
| serve-expired | 过期缓存服务功能 | yes | [yes\|no],开启此功能后,如果有请求时尝试回应 TTL 为 0 的过期记录,并发查询记录,以避免查询等待 | | serve-expired | 过期缓存服务功能 | yes | [yes\|no],开启此功能后,如果有请求时尝试回应 TTL 为 0 的过期记录,并发查询记录,以避免查询等待 |
| serve-expired-ttl | 过期缓存服务最长超时时间 | 0 | 秒0 表示停用超时,大于 0 表示指定的超时的秒数 | serve-expired-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-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 | 双栈 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 | | user | 进程运行用户 | root | user [username] | user nobody |
| ca-file | 证书文件 | /etc/ssl/<br />certs/ca-certificates.crt | 合法路径字符串 | ca-file /etc/ssl/certs/ca-certificates.crt | | 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 | | ca-path | 证书文件路径 | /etc/ssl/certs | 合法路径字符串 | ca-path /etc/ssl/certs |

View File

@@ -167,6 +167,8 @@ 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|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.ipk|Openwrt management interface.
|openwrt LUCI|luci-app-smartdns.xxxxxxxxx.all-luci-compat-all|Compat Openwrt management interface for early openwrt. |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. - 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.
@@ -176,7 +178,6 @@ Download the matching version of the SmartDNS installation package. The correspo
```shell ```shell
https://github.com/pymumu/smartdns/releases https://github.com/pymumu/smartdns/releases
``` ```
- For MacOS, Windows, you can try rust version of smartdns: [SmartDNS-rs](https://github.com/mokeyish/smartdns-rs)
- For the installation procedure, please refer to the following sections. - For the installation procedure, please refer to the following sections.
@@ -476,7 +477,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
1. Install smartdns 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 ```shell
D:\SMARTDNS D:\SMARTDNS
@@ -540,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 |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|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-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-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 |cache-file|cache persist file|/tmp/<br />smartdns.cache|path|cache-file /tmp/smartdns.cache
@@ -562,10 +563,10 @@ 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-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 |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 |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|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-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-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-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| |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 |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 | |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 |
@@ -575,26 +576,27 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|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|no|[yes\|no]|ipset-timeout yes |ipset-timeout|ipset timeout enable|no|[yes\|no]|ipset-timeout yes
|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:ipse6 <br /> ipset-no-speed ipset| |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|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-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-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 |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 />[-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-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 | | 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 |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], 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], RepeatableWhen the filtering server responds IPs in the IP blacklist, The result will be discarded directly| blacklist-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-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 |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 |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 |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|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-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|second0disable> 0 seconds after expiration|serve-expired-reply-ttl 30 |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|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 |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-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 |ca-path|certificates path|/etc/ssl/certs|path|ca-path /etc/ssl/certs

View File

@@ -23,7 +23,7 @@ ifndef CFLAGS
ifdef DEBUG ifdef DEBUG
CFLAGS = -g CFLAGS = -g
else else
CFLAGS = -O2 -g CFLAGS = -O2
endif endif
CFLAGS +=-Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables -Wmissing-prototypes -Wshadow -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough CFLAGS +=-Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables -Wmissing-prototypes -Wshadow -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough
endif endif

View File

@@ -1687,13 +1687,13 @@ static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_co
return 0; return 0;
} }
if (opt_len < (int)member_size(struct dns_opt_cookie, server_cookie)) { if (opt_len < 8 || opt_len > (int)member_size(struct dns_opt_cookie, server_cookie)) {
return -1; return -1;
} }
memcpy(cookie->server_cookie, context->ptr, len); memcpy(cookie->server_cookie, context->ptr, opt_len);
cookie->server_cookie_len = len; cookie->server_cookie_len = opt_len;
context->ptr += len; context->ptr += opt_len;
tlog(TLOG_DEBUG, "OPT COOKIE"); tlog(TLOG_DEBUG, "OPT COOKIE");
return 0; return 0;
@@ -1860,8 +1860,8 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
} }
if (errcode != 0) { if (errcode != 0) {
tlog(TLOG_ERROR, "extend rcode invalid."); tlog(TLOG_DEBUG, "extend rcode invalid, %d", errcode);
return -1; return 0;
} }
while (context->ptr - start < rr_len) { while (context->ptr - start < rr_len) {

View File

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

View File

@@ -2186,6 +2186,11 @@ static int _dns_client_process_udp_proxy(struct dns_server_info *server_info, st
return ret; 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", tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d",
get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len); get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len);
@@ -3280,6 +3285,9 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
continue; continue;
} }
server_info->prohibit = 0; server_info->prohibit = 0;
if (now - 60 > server_info->last_send) {
_dns_client_close_socket(server_info);
}
} }
total_server++; total_server++;
tlog(TLOG_DEBUG, "send query to server %s", server_info->ip); tlog(TLOG_DEBUG, "send query to server %s", server_info->ip);
@@ -3291,6 +3299,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
} }
atomic_inc(&query->dns_request_sent); atomic_inc(&query->dns_request_sent);
errno = 0;
switch (server_info->type) { switch (server_info->type) {
case DNS_SERVER_UDP: case DNS_SERVER_UDP:
/* udp query */ /* udp query */

View File

@@ -132,7 +132,7 @@ struct dns_conf_address_rule dns_conf_address_rule;
/* dual-stack selection */ /* dual-stack selection */
int dns_conf_dualstack_ip_selection = 1; int dns_conf_dualstack_ip_selection = 1;
int dns_conf_dualstack_ip_allow_force_AAAA; 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 */ /* TTL */
int dns_conf_rr_ttl; int dns_conf_rr_ttl;
@@ -3283,10 +3283,6 @@ static int _dns_conf_load_post(void)
dns_conf_rr_ttl_max = dns_conf_rr_ttl_min; 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') { if (dns_resolv_file[0] == '\0') {
safe_strncpy(dns_resolv_file, DNS_RESOLV_FILE, sizeof(dns_resolv_file)); safe_strncpy(dns_resolv_file, DNS_RESOLV_FILE, sizeof(dns_resolv_file));
} }

View File

@@ -85,10 +85,12 @@ typedef enum {
DNS_BIND_TYPE_TLS, DNS_BIND_TYPE_TLS,
} DNS_BIND_TYPE; } DNS_BIND_TYPE;
#define DOMAIN_CHECK_NONE 0 typedef enum {
#define DOMAIN_CHECK_ICMP 1 DOMAIN_CHECK_NONE = 0,
#define DOMAIN_CHECK_TCP 2 DOMAIN_CHECK_ICMP = 1,
#define DOMAIN_CHECK_NUM 3 DOMAIN_CHECK_TCP = 2,
DOMAIN_CHECK_NUM = 3,
} DOMAIN_CHECK_TYPE;
#define DOMAIN_FLAG_ADDR_SOA (1 << 0) #define DOMAIN_FLAG_ADDR_SOA (1 << 0)
#define DOMAIN_FLAG_ADDR_IPV4_SOA (1 << 1) #define DOMAIN_FLAG_ADDR_IPV4_SOA (1 << 1)
@@ -215,7 +217,7 @@ struct dns_server_groups {
}; };
struct dns_domain_check_order { struct dns_domain_check_order {
char type; DOMAIN_CHECK_TYPE type;
unsigned short tcp_port; unsigned short tcp_port;
}; };

View File

@@ -52,6 +52,7 @@
#define DNS_SERVER_TMOUT_TTL (5 * 60) #define DNS_SERVER_TMOUT_TTL (5 * 60)
#define DNS_SERVER_FAIL_TTL (60) #define DNS_SERVER_FAIL_TTL (60)
#define DNS_SERVER_SOA_TTL (30) #define DNS_SERVER_SOA_TTL (30)
#define DNS_SERVER_ADDR_TTL (60)
#define DNS_CONN_BUFF_SIZE 4096 #define DNS_CONN_BUFF_SIZE 4096
#define DNS_REQUEST_MAX_TIMEOUT 950 #define DNS_REQUEST_MAX_TIMEOUT 950
#define DNS_PING_TIMEOUT (DNS_REQUEST_MAX_TIMEOUT) #define DNS_PING_TIMEOUT (DNS_REQUEST_MAX_TIMEOUT)
@@ -238,6 +239,7 @@ struct dns_request {
/* send original raw packet to server/client like proxy */ /* send original raw packet to server/client like proxy */
int passthrough; int passthrough;
int request_wait; int request_wait;
int prefetch; int prefetch;
int prefetch_expired_domain; int prefetch_expired_domain;
@@ -260,10 +262,14 @@ struct dns_request {
DECLARE_HASHTABLE(ip_map, 4); DECLARE_HASHTABLE(ip_map, 4);
struct dns_domain_rule domain_rule; struct dns_domain_rule domain_rule;
int skip_domain_rule;
struct dns_domain_check_orders *check_order_list; struct dns_domain_check_orders *check_order_list;
int check_order; int check_order;
struct dns_request_pending_list *request_pending_list; struct dns_request_pending_list *request_pending_list;
int no_select_possible_ip;
int no_cache_cname;
}; };
/* dns server data */ /* dns server data */
@@ -293,11 +299,13 @@ static int _dns_server_get_answer(struct dns_server_post_context *context);
static void _dns_server_request_get(struct dns_request *request); static void _dns_server_request_get(struct dns_request *request);
static void _dns_server_request_release(struct dns_request *request); static void _dns_server_request_release(struct dns_request *request);
static void _dns_server_request_release_complete(struct dns_request *request, int do_complete); static void _dns_server_request_release_complete(struct dns_request *request, int do_complete);
static int _dns_server_request_complete(struct dns_request *request);
static int _dns_server_reply_passthrough(struct dns_server_post_context *context); static int _dns_server_reply_passthrough(struct dns_server_post_context *context);
static int _dns_server_do_query(struct dns_request *request, int skip_notify_event); static int _dns_server_do_query(struct dns_request *request, int skip_notify_event);
static int _dns_request_post(struct dns_server_post_context *context); static int _dns_request_post(struct dns_server_post_context *context);
static int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context); static int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context);
static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_rule rule); static void *_dns_server_get_dns_rule(struct dns_request *request, enum domain_rule rule);
static const char *_dns_server_get_request_groupname(struct dns_request *request);
static void _dns_server_wakeup_thread(void) static void _dns_server_wakeup_thread(void)
{ {
@@ -308,7 +316,6 @@ static void _dns_server_wakeup_thread(void)
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len) static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
{ {
tlog(TLOG_DEBUG, "forward request.\n");
return -1; return -1;
} }
@@ -333,12 +340,19 @@ static int _dns_server_get_conf_ttl(struct dns_request *request, int ttl)
rr_ttl = ttl_rule->ttl; rr_ttl = ttl_rule->ttl;
} }
/* make domain rule ttl high priority */
if (ttl_rule->ttl_min > 0) { if (ttl_rule->ttl_min > 0) {
rr_ttl_min = ttl_rule->ttl_min; rr_ttl_min = ttl_rule->ttl_min;
if (dns_conf_rr_ttl_max <= rr_ttl_min && dns_conf_rr_ttl_max > 0) {
rr_ttl_max = rr_ttl_min;
}
} }
if (ttl_rule->ttl_max > 0) { if (ttl_rule->ttl_max > 0) {
rr_ttl_max = ttl_rule->ttl_max; rr_ttl_max = ttl_rule->ttl_max;
if (dns_conf_rr_ttl_min >= rr_ttl_max && dns_conf_rr_ttl_min > 0 && ttl_rule->ttl_min <= 0) {
rr_ttl_min = rr_ttl_max;
}
} }
} }
@@ -346,6 +360,11 @@ static int _dns_server_get_conf_ttl(struct dns_request *request, int ttl)
return rr_ttl; return rr_ttl;
} }
/* make rr_ttl_min first priority */
if (rr_ttl_max < rr_ttl_min && rr_ttl_max > 0) {
rr_ttl_max = rr_ttl_min;
}
if (rr_ttl_max > 0 && ttl >= rr_ttl_max) { if (rr_ttl_max > 0 && ttl >= rr_ttl_max) {
ttl = rr_ttl_max; ttl = rr_ttl_max;
} else if (rr_ttl_min > 0 && ttl <= rr_ttl_min) { } else if (rr_ttl_min > 0 && ttl <= rr_ttl_min) {
@@ -388,6 +407,23 @@ static int _dns_server_is_dns_rule_extract_match(struct dns_request *request, en
return request->domain_rule.is_sub_rule[rule] == 0; return request->domain_rule.is_sub_rule[rule] == 0;
} }
static int _dns_server_is_dns64_request(struct dns_request *request)
{
if (request->qtype != DNS_T_AAAA) {
return 0;
}
if (request->dualstack_selection_query == 1) {
return 0;
}
if (dns_conf_dns_dns64.prefix_len <= 0) {
return 0;
}
return 1;
}
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;
@@ -1096,7 +1132,7 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ
} else { } else {
ttl = dns_conf_rr_ttl; ttl = dns_conf_rr_ttl;
if (ttl == 0) { if (ttl == 0) {
ttl = DNS_SERVER_TMOUT_TTL; ttl = _dns_server_get_conf_ttl(request, request->ip_ttl);
} }
} }
@@ -1159,7 +1195,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
struct dns_request *request = context->request; struct dns_request *request = context->request;
if (request->has_cname == 0) { if (request->has_cname == 0 || request->no_cache_cname == 1) {
return 0; return 0;
} }
@@ -1615,6 +1651,7 @@ static int _dns_result_child_post(struct dns_server_post_context *context)
parent_context.do_audit = context->do_audit; parent_context.do_audit = context->do_audit;
parent_context.do_reply = context->do_reply; parent_context.do_reply = context->do_reply;
parent_context.reply_ttl = context->reply_ttl; parent_context.reply_ttl = context->reply_ttl;
parent_context.cache_ttl = context->cache_ttl;
parent_context.skip_notify_count = context->skip_notify_count; parent_context.skip_notify_count = context->skip_notify_count;
parent_context.select_all_best_ip = 1; parent_context.select_all_best_ip = 1;
parent_context.no_release_parent = context->no_release_parent; parent_context.no_release_parent = context->no_release_parent;
@@ -1624,7 +1661,7 @@ static int _dns_result_child_post(struct dns_server_post_context *context)
} }
if (context->no_release_parent == 0) { if (context->no_release_parent == 0) {
tlog(TLOG_INFO, "query %s with child %s done", parent_request->domain, request->domain); tlog(TLOG_DEBUG, "query %s with child %s done", parent_request->domain, request->domain);
request->parent_request = NULL; request->parent_request = NULL;
parent_request->request_wait--; parent_request->request_wait--;
_dns_server_request_release(parent_request); _dns_server_request_release(parent_request);
@@ -1715,7 +1752,7 @@ static int _dns_server_reply_SOA(int rcode, struct dns_request *request)
{ {
/* return SOA record */ /* return SOA record */
request->rcode = rcode; request->rcode = rcode;
if (request->ip_ttl == 0) { if (request->ip_ttl <= 0) {
request->ip_ttl = DNS_SERVER_SOA_TTL; request->ip_ttl = DNS_SERVER_SOA_TTL;
} }
@@ -1769,7 +1806,7 @@ static int _dns_server_reply_all_pending_list(struct dns_request *request, struc
context_pending.do_force_soa = context->do_force_soa; context_pending.do_force_soa = context->do_force_soa;
context_pending.do_ipset = 0; context_pending.do_ipset = 0;
context_pending.reply_ttl = request->ip_ttl; context_pending.reply_ttl = request->ip_ttl;
context_pending.no_release_parent = context->no_release_parent; context_pending.no_release_parent = 0;
_dns_server_reply_passthrough(&context_pending); _dns_server_reply_passthrough(&context_pending);
req->request_pending_list = NULL; req->request_pending_list = NULL;
@@ -1783,6 +1820,34 @@ static int _dns_server_reply_all_pending_list(struct dns_request *request, struc
return ret; return ret;
} }
static void _dns_server_check_complete_dualstack(struct dns_request *request, struct dns_request *dualstack_request)
{
if (dualstack_request == NULL || request == NULL) {
return;
}
if (dualstack_request->qtype == DNS_T_A && dns_conf_dualstack_ip_allow_force_AAAA == 0) {
return;
}
if (dualstack_request->ping_time > 0) {
return;
}
if (dualstack_request->dualstack_selection_query == 1) {
return;
}
if (request->ping_time <= (dns_conf_dualstack_ip_selection_threshold * 10)) {
return;
}
dualstack_request->dualstack_selection_has_ip = request->has_ip;
dualstack_request->dualstack_selection_ping_time = request->ping_time;
dualstack_request->dualstack_selection_force_soa = 1;
_dns_server_request_complete(dualstack_request);
}
static int _dns_server_force_dualstack(struct dns_request *request) static int _dns_server_force_dualstack(struct dns_request *request)
{ {
/* for dualstack request as first pending request, check if need to choose another request*/ /* for dualstack request as first pending request, check if need to choose another request*/
@@ -1791,6 +1856,8 @@ static int _dns_server_force_dualstack(struct dns_request *request)
request->dualstack_selection_has_ip = dualstack_request->has_ip; request->dualstack_selection_has_ip = dualstack_request->has_ip;
request->dualstack_selection_ping_time = dualstack_request->ping_time; request->dualstack_selection_ping_time = dualstack_request->ping_time;
request->dualstack_selection = 1; request->dualstack_selection = 1;
/* if another request still waiting for ping, force complete another request */
_dns_server_check_complete_dualstack(request, dualstack_request);
} }
if (request->dualstack_selection_ping_time < 0 || request->dualstack_selection == 0) { if (request->dualstack_selection_ping_time < 0 || request->dualstack_selection == 0) {
@@ -2009,6 +2076,10 @@ static void _dns_server_select_possible_ipaddress(struct dns_request *request)
return; return;
} }
if (request->no_select_possible_ip != 0) {
return;
}
if (request->ping_time > 0) { if (request->ping_time > 0) {
return; return;
} }
@@ -2048,14 +2119,14 @@ static void _dns_server_select_possible_ipaddress(struct dns_request *request)
switch (request->qtype) { switch (request->qtype) {
case DNS_T_A: { case DNS_T_A: {
memcpy(request->ip_addr, selected_addr_map->ip_addr, DNS_RR_A_LEN); memcpy(request->ip_addr, selected_addr_map->ip_addr, DNS_RR_A_LEN);
request->ip_ttl = DNS_SERVER_TMOUT_TTL; request->ip_ttl = dns_conf_rr_ttl_min > 0 ? dns_conf_rr_ttl_min : DNS_SERVER_TMOUT_TTL;
tlog(TLOG_DEBUG, "possible result: %s, rcode: %d, hitnum: %d, %d.%d.%d.%d", request->domain, request->rcode, tlog(TLOG_DEBUG, "possible result: %s, rcode: %d, hitnum: %d, %d.%d.%d.%d", request->domain, request->rcode,
selected_addr_map->hitnum, request->ip_addr[0], request->ip_addr[1], request->ip_addr[2], selected_addr_map->hitnum, request->ip_addr[0], request->ip_addr[1], request->ip_addr[2],
request->ip_addr[3]); request->ip_addr[3]);
} break; } break;
case DNS_T_AAAA: { case DNS_T_AAAA: {
memcpy(request->ip_addr, selected_addr_map->ip_addr, DNS_RR_AAAA_LEN); memcpy(request->ip_addr, selected_addr_map->ip_addr, DNS_RR_AAAA_LEN);
request->ip_ttl = DNS_SERVER_TMOUT_TTL; request->ip_ttl = dns_conf_rr_ttl_min > 0 ? dns_conf_rr_ttl_min : DNS_SERVER_TMOUT_TTL;
tlog(TLOG_DEBUG, tlog(TLOG_DEBUG,
"possible result: %s, rcode: %d, hitnum: %d, " "possible result: %s, rcode: %d, hitnum: %d, "
"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
@@ -2786,9 +2857,14 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
} }
safe_strncpy(cname, domain_cname, DNS_MAX_CNAME_LEN); safe_strncpy(cname, domain_cname, DNS_MAX_CNAME_LEN);
request->ttl_cname = _dns_server_get_conf_ttl(request, ttl); request->ttl_cname = _dns_server_get_conf_ttl(request, ttl);
tlog(TLOG_DEBUG, "name: %s ttl: %d cname: %s\n", name, ttl, cname); tlog(TLOG_DEBUG, "name: %s ttl: %d cname: %s\n", domain_name, ttl, cname);
} break; } break;
case DNS_T_SOA: { case DNS_T_SOA: {
/* if DNS64 enabled, skip check SOA. */
if (_dns_server_is_dns64_request(request)) {
break;
}
request->has_soa = 1; request->has_soa = 1;
if (request->rcode != DNS_RC_NOERROR) { if (request->rcode != DNS_RC_NOERROR) {
request->rcode = packet->head.rcode; request->rcode = packet->head.rcode;
@@ -2800,11 +2876,6 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d
domain, request->qtype, request->soa.mname, request->soa.rname, request->soa.serial, domain, request->qtype, request->soa.mname, request->soa.rname, request->soa.serial,
request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum); request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
/* if DNS64 enabled, skip check SOA. */
if (request->qtype == DNS_T_AAAA && dns_conf_dns_dns64.prefix_len > 0) {
break;
}
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; request->ip_ttl = ttl;
@@ -3043,7 +3114,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
char cname[DNS_MAX_CNAME_LEN]; char cname[DNS_MAX_CNAME_LEN];
char name[DNS_MAX_CNAME_LEN] = {0}; char name[DNS_MAX_CNAME_LEN] = {0};
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN); dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
tlog(TLOG_DEBUG, "NS: %s ttl: %d cname: %s\n", name, ttl, cname); tlog(TLOG_DEBUG, "NS: %s, ttl: %d, cname: %s\n", name, ttl, cname);
} break; } break;
case DNS_T_CNAME: { case DNS_T_CNAME: {
char cname[DNS_MAX_CNAME_LEN]; char cname[DNS_MAX_CNAME_LEN];
@@ -3053,7 +3124,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
} }
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN); dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
tlog(TLOG_DEBUG, "name: %s ttl: %d cname: %s\n", name, ttl, cname); tlog(TLOG_DEBUG, "name: %s, ttl: %d, cname: %s\n", name, ttl, cname);
if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 && if (strncmp(name, request->domain, DNS_MAX_CNAME_LEN - 1) != 0 &&
strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) { strncmp(name, request->cname, DNS_MAX_CNAME_LEN - 1) != 0) {
continue; continue;
@@ -3139,7 +3210,12 @@ static void _dns_server_query_end(struct dns_request *request)
/* Not need to wait check result if only has one ip address */ /* Not need to wait check result if only has one ip address */
if (ip_num == 1 && request_wait == 1) { if (ip_num == 1 && request_wait == 1) {
if (request->dualstack_selection_query == 1) { if (request->dualstack_selection_query == 1) {
if ((dns_conf_ipset_no_speed.ipv4_enable || dns_conf_nftset_no_speed.ip6_enable ||
dns_conf_ipset_no_speed.ipv6_enable || dns_conf_nftset_no_speed.ip6_enable) &&
dns_conf_dns_dns64.prefix_len == 0) {
/* if speed check fail enabled, we need reply quickly, otherwise wait for ping result.*/
_dns_server_request_complete(request); _dns_server_request_complete(request);
}
goto out; goto out;
} }
@@ -3687,7 +3763,7 @@ static int _dns_server_get_rules(unsigned char *key, uint32_t key_len, int is_su
return 0; return 0;
} }
static void _dns_server_get_domain_rule(struct dns_request *request) static void _dns_server_get_domain_rule_by_domain(struct dns_request *request, const char *domain, int out_log)
{ {
int domain_len = 0; int domain_len = 0;
char domain_key[DNS_MAX_CNAME_LEN]; char domain_key[DNS_MAX_CNAME_LEN];
@@ -3696,12 +3772,16 @@ static void _dns_server_get_domain_rule(struct dns_request *request)
struct rule_walk_args walk_args; struct rule_walk_args walk_args;
int i = 0; int i = 0;
if (request->skip_domain_rule != 0) {
return;
}
memset(&walk_args, 0, sizeof(walk_args)); memset(&walk_args, 0, sizeof(walk_args));
walk_args.args = request; walk_args.args = request;
/* reverse domain string */ /* reverse domain string */
domain_len = strlen(request->domain); domain_len = strlen(domain);
reverse_string(domain_key, request->domain, domain_len, 1); reverse_string(domain_key, domain, domain_len, 1);
domain_key[domain_len] = '.'; domain_key[domain_len] = '.';
domain_len++; domain_len++;
domain_key[domain_len] = 0; domain_key[domain_len] = 0;
@@ -3728,10 +3808,19 @@ static void _dns_server_get_domain_rule(struct dns_request *request)
matched_key_len--; matched_key_len--;
matched_key[matched_key_len] = 0; matched_key[matched_key_len] = 0;
if (out_log != 0) {
_dns_server_log_rule(request->domain, i, matched_key, matched_key_len); _dns_server_log_rule(request->domain, i, matched_key, matched_key_len);
} }
} }
request->skip_domain_rule = 1;
}
static void _dns_server_get_domain_rule(struct dns_request *request)
{
_dns_server_get_domain_rule_by_domain(request, request->domain, 1);
}
static int _dns_server_pre_process_rule_flags(struct dns_request *request) static int _dns_server_pre_process_rule_flags(struct dns_request *request)
{ {
struct dns_rule_flags *rule_flag = NULL; struct dns_rule_flags *rule_flag = NULL;
@@ -3800,6 +3889,34 @@ soa:
return 0; return 0;
} }
static int _dns_server_get_local_ttl(struct dns_request *request)
{
struct dns_ttl_rule *ttl_rule;
/* get domain rule flag */
ttl_rule = _dns_server_get_dns_rule(request, DOMAIN_RULE_TTL);
if (ttl_rule != NULL) {
if (ttl_rule->ttl > 0) {
return ttl_rule->ttl;
}
}
if (dns_conf_local_ttl > 0) {
return dns_conf_local_ttl;
}
if (dns_conf_rr_ttl > 0) {
return dns_conf_rr_ttl;
}
if (dns_conf_rr_ttl_min > 0) {
return dns_conf_rr_ttl_min;
}
return DNS_SERVER_ADDR_TTL;
}
static int _dns_server_process_address(struct dns_request *request) static int _dns_server_process_address(struct dns_request *request)
{ {
struct dns_rule_address_IPV4 *address_ipv4 = NULL; struct dns_rule_address_IPV4 *address_ipv4 = NULL;
@@ -3831,7 +3948,7 @@ static int _dns_server_process_address(struct dns_request *request)
} }
request->rcode = DNS_RC_NOERROR; request->rcode = DNS_RC_NOERROR;
request->ip_ttl = dns_conf_local_ttl; request->ip_ttl = _dns_server_get_local_ttl(request);
request->has_ip = 1; request->has_ip = 1;
struct dns_server_post_context context; struct dns_server_post_context context;
@@ -3846,8 +3963,8 @@ errout:
return -1; return -1;
} }
static struct dns_request *_dns_server_new_child_request(struct dns_request *request, static struct dns_request *_dns_server_new_child_request(struct dns_request *request, const char *domain,
child_request_callback child_callback) dns_type_t qtype, child_request_callback child_callback)
{ {
struct dns_request *child_request = NULL; struct dns_request *child_request = NULL;
@@ -3859,10 +3976,14 @@ static struct dns_request *_dns_server_new_child_request(struct dns_request *req
child_request->server_flags = request->server_flags; child_request->server_flags = request->server_flags;
safe_strncpy(child_request->dns_group_name, request->dns_group_name, sizeof(request->dns_group_name)); safe_strncpy(child_request->dns_group_name, request->dns_group_name, sizeof(request->dns_group_name));
safe_strncpy(child_request->domain, domain, sizeof(child_request->domain));
child_request->prefetch = request->prefetch; child_request->prefetch = request->prefetch;
child_request->prefetch_expired_domain = request->prefetch_expired_domain; child_request->prefetch_expired_domain = request->prefetch_expired_domain;
child_request->child_callback = child_callback; child_request->child_callback = child_callback;
child_request->parent_request = request; child_request->parent_request = request;
child_request->qtype = qtype;
child_request->qclass = request->qclass;
if (request->has_ecs) { if (request->has_ecs) {
memcpy(&child_request->ecs, &request->ecs, sizeof(child_request->ecs)); memcpy(&child_request->ecs, &request->ecs, sizeof(child_request->ecs));
child_request->has_ecs = request->has_ecs; child_request->has_ecs = request->has_ecs;
@@ -3870,6 +3991,7 @@ static struct dns_request *_dns_server_new_child_request(struct dns_request *req
_dns_server_request_get(request); _dns_server_request_get(request);
/* reference count is 1 hold by parent request */ /* reference count is 1 hold by parent request */
request->child_request = child_request; request->child_request = child_request;
_dns_server_get_domain_rule(child_request);
return child_request; return child_request;
errout: errout:
if (child_request) { if (child_request) {
@@ -3891,7 +4013,7 @@ static int _dns_server_request_copy(struct dns_request *request, struct dns_requ
if (from->has_ip) { if (from->has_ip) {
request->has_ip = 1; request->has_ip = 1;
request->ip_ttl = from->ip_ttl; request->ip_ttl = _dns_server_get_conf_ttl(request, from->ip_ttl);
request->ping_time = from->ping_time; request->ping_time = from->ping_time;
memcpy(request->ip_addr, from->ip_addr, sizeof(request->ip_addr)); memcpy(request->ip_addr, from->ip_addr, sizeof(request->ip_addr));
} }
@@ -3952,14 +4074,57 @@ static DNS_CHILD_POST_RESULT _dns_server_process_cname_callback(struct dns_reque
struct dns_request *child_request, int is_first_resp) struct dns_request *child_request, int is_first_resp)
{ {
_dns_server_request_copy(request, child_request); _dns_server_request_copy(request, child_request);
if (child_request->rcode == DNS_RC_NOERROR && dns_conf_force_no_cname == 0 && child_request->has_soa == 0) {
safe_strncpy(request->cname, child_request->domain, sizeof(request->cname)); safe_strncpy(request->cname, child_request->domain, sizeof(request->cname));
request->has_cname = 1;
request->ttl_cname = _dns_server_get_conf_ttl(request, child_request->ip_ttl);
}
return DNS_CHILD_POST_SUCCESS; return DNS_CHILD_POST_SUCCESS;
} }
static int _dns_server_process_cname_pre(struct dns_request *request)
{
struct dns_cname_rule *cname = NULL;
struct dns_rule_flags *rule_flag = NULL;
struct dns_domain_rule domain_rule;
if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_RULE_CNAME) == 0) {
return 0;
}
/* get domain rule flag */
rule_flag = _dns_server_get_dns_rule(request, DOMAIN_RULE_FLAGS);
if (rule_flag != NULL) {
if (rule_flag->flags & DOMAIN_FLAG_CNAME_IGN) {
return 0;
}
}
cname = _dns_server_get_dns_rule(request, DOMAIN_RULE_CNAME);
if (cname == NULL) {
return 0;
}
request->skip_domain_rule = 0;
/* copy child rules */
memcpy(&domain_rule, &request->domain_rule, sizeof(domain_rule));
memset(&request->domain_rule, 0, sizeof(request->domain_rule));
_dns_server_get_domain_rule_by_domain(request, cname->cname, 0);
request->domain_rule.rules[DOMAIN_RULE_CNAME] = domain_rule.rules[DOMAIN_RULE_CNAME];
request->domain_rule.is_sub_rule[DOMAIN_RULE_CNAME] = domain_rule.is_sub_rule[DOMAIN_RULE_CNAME];
request->no_select_possible_ip = 1;
request->no_cache_cname = 1;
safe_strncpy(request->cname, cname->cname, sizeof(request->cname));
return 0;
}
static int _dns_server_process_cname(struct dns_request *request) static int _dns_server_process_cname(struct dns_request *request)
{ {
struct dns_cname_rule *cname = NULL; struct dns_cname_rule *cname = NULL;
const char *child_group_name = NULL;
int ret = 0; int ret = 0;
struct dns_rule_flags *rule_flag = NULL; struct dns_rule_flags *rule_flag = NULL;
@@ -3975,11 +4140,6 @@ static int _dns_server_process_cname(struct dns_request *request)
} }
} }
/* cname /domain/ rule */
if (request->domain_rule.rules[DOMAIN_RULE_CNAME] == NULL) {
return 0;
}
cname = _dns_server_get_dns_rule(request, DOMAIN_RULE_CNAME); cname = _dns_server_get_dns_rule(request, DOMAIN_RULE_CNAME);
if (cname == NULL) { if (cname == NULL) {
return 0; return 0;
@@ -3987,15 +4147,18 @@ static int _dns_server_process_cname(struct dns_request *request)
tlog(TLOG_INFO, "query %s with cname %s", request->domain, cname->cname); tlog(TLOG_INFO, "query %s with cname %s", request->domain, cname->cname);
struct dns_request *child_request = _dns_server_new_child_request(request, _dns_server_process_cname_callback); struct dns_request *child_request =
_dns_server_new_child_request(request, cname->cname, request->qtype, _dns_server_process_cname_callback);
if (child_request == NULL) { if (child_request == NULL) {
tlog(TLOG_ERROR, "malloc failed.\n"); tlog(TLOG_ERROR, "malloc failed.\n");
return -1; return -1;
} }
child_request->qtype = request->qtype; child_group_name = _dns_server_get_request_groupname(child_request);
child_request->qclass = request->qclass; if (child_group_name) {
safe_strncpy(child_request->domain, cname->cname, sizeof(child_request->cname)); /* reset dns group and setup child request domain group again when do query.*/
child_request->dns_group_name[0] = '\0';
}
request->request_wait++; request->request_wait++;
ret = _dns_server_do_query(child_request, 0); ret = _dns_server_do_query(child_request, 0);
@@ -4037,6 +4200,12 @@ _dns_server_process_dns64_callback(struct dns_request *request, struct dns_reque
return DNS_CHILD_POST_FAIL; return DNS_CHILD_POST_FAIL;
} }
if (child_request->has_cname == 1) {
safe_strncpy(request->cname, child_request->cname, sizeof(request->cname));
request->has_cname = 1;
request->ttl_cname = child_request->ttl_cname;
}
if (child_request->has_ip == 0) { if (child_request->has_ip == 0) {
if (child_request->has_soa) { if (child_request->has_soa) {
memcpy(&request->soa, &child_request->soa, sizeof(struct dns_soa)); memcpy(&request->soa, &child_request->soa, sizeof(struct dns_soa));
@@ -4108,27 +4277,19 @@ _dns_server_process_dns64_callback(struct dns_request *request, struct dns_reque
static int _dns_server_process_dns64(struct dns_request *request) static int _dns_server_process_dns64(struct dns_request *request)
{ {
if (request->qtype != DNS_T_AAAA) { if (_dns_server_is_dns64_request(request) == 0) {
return 0;
}
if (dns_conf_dns_dns64.prefix_len <= 0) {
/* no dns64 prefix, no need to do dns64 */
return 0; return 0;
} }
tlog(TLOG_DEBUG, "query %s with dns64", request->domain); tlog(TLOG_DEBUG, "query %s with dns64", request->domain);
struct dns_request *child_request = _dns_server_new_child_request(request, _dns_server_process_dns64_callback); struct dns_request *child_request =
_dns_server_new_child_request(request, request->domain, DNS_T_A, _dns_server_process_dns64_callback);
if (child_request == NULL) { if (child_request == NULL) {
tlog(TLOG_ERROR, "malloc failed.\n"); tlog(TLOG_ERROR, "malloc failed.\n");
return -1; return -1;
} }
child_request->qtype = DNS_T_A;
child_request->qclass = request->qclass;
safe_strncpy(child_request->domain, request->domain, sizeof(child_request->domain));
request->request_wait++; request->request_wait++;
int ret = _dns_server_do_query(child_request, 0); int ret = _dns_server_do_query(child_request, 0);
if (ret != 0) { if (ret != 0) {
@@ -4190,10 +4351,6 @@ static int _dns_server_get_expired_ttl_reply(struct dns_cache *dns_cache)
{ {
int ttl = dns_cache_get_ttl(dns_cache); int ttl = dns_cache_get_ttl(dns_cache);
if (ttl > 0) { if (ttl > 0) {
if (dns_conf_rr_ttl_reply_max > 0 && ttl > dns_conf_rr_ttl_reply_max) {
ttl = dns_conf_rr_ttl_reply_max;
}
return ttl; return ttl;
} }
@@ -4305,7 +4462,6 @@ static int _dns_server_process_cache_data(struct dns_request *request, struct dn
if (ret != 0) { if (ret != 0) {
goto out; goto out;
} }
break; break;
default: default:
goto out; goto out;
@@ -4358,9 +4514,13 @@ static int _dns_server_process_cache(struct dns_request *request)
cache_key.qtype = dualstack_qtype; cache_key.qtype = dualstack_qtype;
dualstack_dns_cache = dns_cache_lookup(&cache_key); dualstack_dns_cache = dns_cache_lookup(&cache_key);
if (dualstack_dns_cache == NULL && request->cname[0] != '\0') {
cache_key.domain = request->cname;
dualstack_dns_cache = dns_cache_lookup(&cache_key);
}
if (dualstack_dns_cache && dns_cache_is_soa(dualstack_dns_cache) == 0 && if (dualstack_dns_cache && dns_cache_is_soa(dualstack_dns_cache) == 0 &&
(dualstack_dns_cache->info.speed > 0)) { (dualstack_dns_cache->info.speed > 0)) {
if (dns_cache_is_soa(dns_cache)) { if (dns_cache_is_soa(dns_cache)) {
ret = _dns_server_process_cache_packet(request, dns_cache); ret = _dns_server_process_cache_packet(request, dns_cache);
goto out_update_cache; goto out_update_cache;
@@ -4372,6 +4532,7 @@ static int _dns_server_process_cache(struct dns_request *request)
tlog(TLOG_DEBUG, "cache result: %s, qtype: %d, force %s preferred, id: %d, time1: %d, time2: %d", tlog(TLOG_DEBUG, "cache result: %s, qtype: %d, force %s preferred, id: %d, time1: %d, time2: %d",
request->domain, request->qtype, request->qtype == DNS_T_AAAA ? "IPv4" : "IPv6", request->id, request->domain, request->qtype, request->qtype == DNS_T_AAAA ? "IPv4" : "IPv6", request->id,
dns_cache->info.speed, dualstack_dns_cache->info.speed); dns_cache->info.speed, dualstack_dns_cache->info.speed);
request->ip_ttl = _dns_server_get_expired_ttl_reply(dualstack_dns_cache);
ret = _dns_server_reply_SOA(DNS_RC_NOERROR, request); ret = _dns_server_reply_SOA(DNS_RC_NOERROR, request);
goto out_update_cache; goto out_update_cache;
} }
@@ -4705,7 +4866,7 @@ static int _dns_server_query_dualstack(struct dns_request *request)
{ {
int ret = -1; int ret = -1;
struct dns_request *request_dualstack = NULL; struct dns_request *request_dualstack = NULL;
int qtype = request->qtype; dns_type_t qtype = request->qtype;
if (request->dualstack_selection == 0) { if (request->dualstack_selection == 0) {
return 0; return 0;
@@ -4781,6 +4942,10 @@ static int _dns_server_do_query(struct dns_request *request, int skip_notify_eve
safe_strncpy(request->dns_group_name, group_name, DNS_GROUP_NAME_LEN); safe_strncpy(request->dns_group_name, group_name, DNS_GROUP_NAME_LEN);
} }
if (_dns_server_process_cname_pre(request) != 0) {
goto errout;
}
_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) {

View File

@@ -336,7 +336,8 @@ static struct addrinfo *_fast_ping_getaddr(const char *host, const char *port, i
hints.ai_protocol = protocol; hints.ai_protocol = protocol;
errcode = getaddrinfo(host, port, &hints, &result); errcode = getaddrinfo(host, port, &hints, &result);
if (errcode != 0) { 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; goto errout;
} }