Compare commits
15 Commits
Release36.
...
all-best-i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34691154fb | ||
|
|
29a5803860 | ||
|
|
ebd820bcbb | ||
|
|
1de5557430 | ||
|
|
c92615e6cd | ||
|
|
c561ae2fc5 | ||
|
|
d30264ed08 | ||
|
|
22e13b40db | ||
|
|
75dda9340d | ||
|
|
baf2be681d | ||
|
|
5bd521c36b | ||
|
|
d0305f60f6 | ||
|
|
6e1363dca4 | ||
|
|
23e9021d30 | ||
|
|
92af4c05c0 |
@@ -560,6 +560,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
|||||||
| `rr-ttl` | 域名结果 TTL | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl 600` |
|
| `rr-ttl` | 域名结果 TTL | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl 600` |
|
||||||
| `rr-ttl-min` | 允许的最小 TTL 值 | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl-min 60` |
|
| `rr-ttl-min` | 允许的最小 TTL 值 | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl-min 60` |
|
||||||
| `rr-ttl-max` | 允许的最大 TTL 值 | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl-max 600` |
|
| `rr-ttl-max` | 允许的最大 TTL 值 | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl-max 600` |
|
||||||
|
| `rr-ttl-reply-max` | 允许返回给客户端的最大 TTL 值 | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl-reply-max 60` |
|
||||||
| `log-level` | 设置日志级别 | `error` | `fatal`、`error`、`warn`、`notice`、`info` 或 `debug` | `log-level error` |
|
| `log-level` | 设置日志级别 | `error` | `fatal`、`error`、`warn`、`notice`、`info` 或 `debug` | `log-level error` |
|
||||||
| `log-file` | 日志文件路径 | `/var/log/smartdns.log` | 合法路径字符串 | `log-file /var/log/smartdns.log` |
|
| `log-file` | 日志文件路径 | `/var/log/smartdns.log` | 合法路径字符串 | `log-file /var/log/smartdns.log` |
|
||||||
| `log-size` | 日志大小 | `128K` | 数字 + `K`、`M` 或 `G` | `log-size 128K` |
|
| `log-size` | 日志大小 | `128K` | 数字 + `K`、`M` 或 `G` | `log-size 128K` |
|
||||||
@@ -586,11 +587,11 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
|||||||
| `force-AAAA-SOA` | 强制 AAAA 地址返回 SOA | `no` | [`yes`\|`no`] | `force-AAAA-SOA yes` |
|
| `force-AAAA-SOA` | 强制 AAAA 地址返回 SOA | `no` | [`yes`\|`no`] | `force-AAAA-SOA yes` |
|
||||||
| `force-qtype-SOA` | 强制指定 qtype 返回 SOA | qtype id | [`<qtypeid>` \| ...] | `force-qtype-SOA 65 28`
|
| `force-qtype-SOA` | 强制指定 qtype 返回 SOA | qtype id | [`<qtypeid>` \| ...] | `force-qtype-SOA 65 28`
|
||||||
| `prefetch-domain` | 域名预先获取功能 | `no` | [`yes`\|`no`] | `prefetch-domain yes` |
|
| `prefetch-domain` | 域名预先获取功能 | `no` | [`yes`\|`no`] | `prefetch-domain yes` |
|
||||||
| `serve-expired` | 过期缓存服务功能 | `no` | [`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` |
|
||||||
| `dualstack-ip-selection` | 双栈 IP 优选 | `no` | [`yes`\|`no`] | `dualstack-ip-selection yes` |
|
| `dualstack-ip-selection` | 双栈 IP 优选 | `yes` | [`yes`\|`no`] | `dualstack-ip-selection yes` |
|
||||||
| `dualstack-ip-selection-threshold` | 双栈 IP 优选阈值 | `30ms` | 单位为毫秒(`ms`) | `dualstack-ip-selection-threshold [0-1000]` |
|
| `dualstack-ip-selection-threshold` | 双栈 IP 优选阈值 | `15ms` | 单位为毫秒(`ms`) | `dualstack-ip-selection-threshold [0-1000]` |
|
||||||
| `ca-file` | 证书文件 | `/etc/ssl/certs/ca-certificates.crt` | 合法路径字符串 | `ca-file /etc/ssl/certs/ca-certificates.crt` |
|
| `ca-file` | 证书文件 | `/etc/ssl/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` |
|
||||||
|
|
||||||
|
|||||||
@@ -503,6 +503,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|
|||||||
|tcp-idle-time|TCP connection idle timeout|120|integer|tcp-idle-time 120
|
|tcp-idle-time|TCP connection idle timeout|120|integer|tcp-idle-time 120
|
||||||
|rr-ttl|Domain name TTL|Remote query result|number greater than 0|rr-ttl 600
|
|rr-ttl|Domain name TTL|Remote query result|number greater than 0|rr-ttl 600
|
||||||
|rr-ttl-min|Domain name Minimum TTL|Remote query result|number greater than 0|rr-ttl-min 60
|
|rr-ttl-min|Domain name Minimum TTL|Remote query result|number greater than 0|rr-ttl-min 60
|
||||||
|
|rr-ttl-reply-max|Domain name Minimum Reply TTL|Remote query result|number greater than 0|rr-ttl-reply-max 60
|
||||||
|rr-ttl-max|Domain name Maximum TTL|Remote query result|number greater than 0|rr-ttl-max 600
|
|rr-ttl-max|Domain name Maximum TTL|Remote query result|number greater than 0|rr-ttl-max 600
|
||||||
|log-level|log level|error|fatal,error,warn,notice,info,debug|log-level error
|
|log-level|log level|error|fatal,error,warn,notice,info,debug|log-level error
|
||||||
|log-file|log path|/var/log/smartdns.log|File Pah|log-file /var/log/smartdns.log
|
|log-file|log path|/var/log/smartdns.log|File Pah|log-file /var/log/smartdns.log
|
||||||
@@ -530,11 +531,11 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|
|||||||
|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
|
||||||
|serve-expired|Cache serve expired feature|no|[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 limite TTL|0|second,0:disable,> 0 seconds after expiration|serve-expired-ttl 0
|
|serve-expired-ttl|Cache serve expired limite 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-reply-ttl|TTL value to use when replying with expired data|5|second,0:disable,> 0 seconds after expiration|serve-expired-reply-ttl 30
|
||||||
|dualstack-ip-selection|Dualstack ip selection|no|[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 threadhold|30ms|millisecond|dualstack-ip-selection-threshold [0-1000]
|
|dualstack-ip-selection-threshold|Dualstack ip select threadhold|15ms|millisecond|dualstack-ip-selection-threshold [0-1000]
|
||||||
|ca-file|certificate file|/etc/ssl/certs/ca-certificates.crt|path|ca-file /etc/ssl/certs/ca-certificates.crt
|
|ca-file|certificate file|/etc/ssl/certs/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
|
||||||
|
|
||||||
|
|||||||
@@ -68,11 +68,23 @@ case $1 in
|
|||||||
echo "Stop smartdns server failed."
|
echo "Stop smartdns server failed."
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
rm -f "$PIDFILE"
|
LOOP=1
|
||||||
|
while true; do
|
||||||
|
if [ ! -d "/proc/$PID" ]; then
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $LOOP -gt 12 ]; then
|
||||||
|
kill -9 "$PID"
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
LOOP=$((LOOP+1))
|
||||||
|
sleep .5
|
||||||
|
done
|
||||||
echo "Stop smartdns server success."
|
echo "Stop smartdns server success."
|
||||||
;;
|
;;
|
||||||
restart)
|
restart)
|
||||||
"$0" stop && sleep 1 && "$0" start
|
"$0" stop && "$0" start
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
PID="$(cat "$PIDFILE" 2>/dev/null)"
|
PID="$(cat "$PIDFILE" 2>/dev/null)"
|
||||||
|
|||||||
@@ -102,10 +102,12 @@ cache-size 4096
|
|||||||
# rr-ttl: ttl for all record
|
# rr-ttl: ttl for all record
|
||||||
# rr-ttl-min: minimum ttl for resource record
|
# rr-ttl-min: minimum ttl for resource record
|
||||||
# rr-ttl-max: maximum ttl for resource record
|
# rr-ttl-max: maximum ttl for resource record
|
||||||
|
# tr-ttl-reply-max: maximum reply ttl for resource record
|
||||||
# example:
|
# example:
|
||||||
# rr-ttl 300
|
# rr-ttl 300
|
||||||
# rr-ttl-min 60
|
# rr-ttl-min 60
|
||||||
# rr-ttl-max 86400
|
# rr-ttl-max 86400
|
||||||
|
# rr-ttl-reply-max 60
|
||||||
|
|
||||||
# set log level
|
# set log level
|
||||||
# log-level: [level], level=fatal, error, warn, notice, info, debug
|
# log-level: [level], level=fatal, error, warn, notice, info, debug
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ msgstr "域名TTL最大值"
|
|||||||
msgid "Maximum TTL for all domain result."
|
msgid "Maximum TTL for all domain result."
|
||||||
msgstr "设置所有域名的TTL最大值"
|
msgstr "设置所有域名的TTL最大值"
|
||||||
|
|
||||||
|
msgid "Maximum Reply TTL for all domain result."
|
||||||
|
msgstr "设置返回给客户端的TTL最大值"
|
||||||
|
|
||||||
msgid "smartdns custom settings"
|
msgid "smartdns custom settings"
|
||||||
msgstr "smartdns 自定义设置,具体配置参数参考指导"
|
msgstr "smartdns 自定义设置,具体配置参数参考指导"
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ end
|
|||||||
---- Support DualStack ip selection
|
---- Support DualStack ip selection
|
||||||
o = s:taboption("settings", Flag, "dualstack_ip_selection", translate("Dual-stack IP Selection"), translate("Enable IP selection between IPV4 and IPV6"))
|
o = s:taboption("settings", Flag, "dualstack_ip_selection", translate("Dual-stack IP Selection"), translate("Enable IP selection between IPV4 and IPV6"))
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
o.default = o.disabled
|
o.default = o.enabled
|
||||||
o.cfgvalue = function(...)
|
o.cfgvalue = function(...)
|
||||||
return Flag.cfgvalue(...) or "0"
|
return Flag.cfgvalue(...) or "0"
|
||||||
end
|
end
|
||||||
@@ -87,7 +87,7 @@ end
|
|||||||
o = s:taboption("settings", Flag, "serve_expired", translate("Serve expired"),
|
o = s:taboption("settings", Flag, "serve_expired", translate("Serve expired"),
|
||||||
translate("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."))
|
translate("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."))
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
o.default = o.disabled
|
o.default = o.enabled
|
||||||
o.cfgvalue = function(...)
|
o.cfgvalue = function(...)
|
||||||
return Flag.cfgvalue(...) or "0"
|
return Flag.cfgvalue(...) or "0"
|
||||||
end
|
end
|
||||||
@@ -112,15 +112,19 @@ o.rempty = true
|
|||||||
---- rr-ttl-min
|
---- rr-ttl-min
|
||||||
o = s:taboption("settings", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result."))
|
o = s:taboption("settings", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result."))
|
||||||
o.rempty = true
|
o.rempty = true
|
||||||
o.placeholder = "300"
|
o.placeholder = "600"
|
||||||
o.default = 300
|
o.default = 600
|
||||||
o.optional = true
|
o.optional = true
|
||||||
|
|
||||||
---- second dns server
|
|
||||||
---- rr-ttl-max
|
---- rr-ttl-max
|
||||||
o = s:taboption("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result."))
|
o = s:taboption("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result."))
|
||||||
o.rempty = true
|
o.rempty = true
|
||||||
|
|
||||||
|
---- rr-ttl-reply-max
|
||||||
|
o = s:taboption("settings", Value, "rr_ttl_reply_max", translate("Domain TTL Max"), translate("Maximum Reply TTL for all domain result."))
|
||||||
|
o.rempty = true
|
||||||
|
|
||||||
|
---- second dns server
|
||||||
---- Eanble
|
---- Eanble
|
||||||
o = s:taboption("seconddns", Flag, "seconddns_enabled", translate("Enable"), translate("Enable or disable second DNS server."))
|
o = s:taboption("seconddns", Flag, "seconddns_enabled", translate("Enable"), translate("Enable or disable second DNS server."))
|
||||||
o.default = o.disabled
|
o.default = o.disabled
|
||||||
|
|||||||
@@ -130,6 +130,9 @@ msgstr "域名TTL最大值"
|
|||||||
msgid "Maximum TTL for all domain result."
|
msgid "Maximum TTL for all domain result."
|
||||||
msgstr "设置所有域名的TTL最大值"
|
msgstr "设置所有域名的TTL最大值"
|
||||||
|
|
||||||
|
msgid "Maximum Reply TTL for all domain result."
|
||||||
|
msgstr "设置返回给客户端的TTL最大值"
|
||||||
|
|
||||||
msgid "smartdns custom settings"
|
msgid "smartdns custom settings"
|
||||||
msgstr "smartdns 自定义设置,具体配置参数参考指导"
|
msgstr "smartdns 自定义设置,具体配置参数参考指导"
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ return L.view.extend({
|
|||||||
o = s.taboption("settings", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"),
|
o = s.taboption("settings", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"),
|
||||||
_("Enable IP selection between IPV4 and IPV6"));
|
_("Enable IP selection between IPV4 and IPV6"));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.default = o.disabled;
|
o.default = o.enabled;
|
||||||
|
|
||||||
// Domain prefetch load ;
|
// Domain prefetch load ;
|
||||||
o = s.taboption("settings", form.Flag, "prefetch_domain", _("Domain prefetch"),
|
o = s.taboption("settings", form.Flag, "prefetch_domain", _("Domain prefetch"),
|
||||||
@@ -200,7 +200,7 @@ return L.view.extend({
|
|||||||
o = s.taboption("settings", form.Flag, "serve_expired", _("Serve expired"),
|
o = s.taboption("settings", form.Flag, "serve_expired", _("Serve expired"),
|
||||||
_("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."));
|
_("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.default = o.disabled;
|
o.default = o.enabled;
|
||||||
|
|
||||||
// Redirect;
|
// Redirect;
|
||||||
o = s.taboption("settings", form.ListValue, "redirect", _("Redirect"), _("SmartDNS redirect mode"));
|
o = s.taboption("settings", form.ListValue, "redirect", _("Redirect"), _("SmartDNS redirect mode"));
|
||||||
@@ -223,16 +223,21 @@ return L.view.extend({
|
|||||||
o = s.taboption("settings", form.Value, "rr_ttl_min", _("Domain TTL Min"),
|
o = s.taboption("settings", form.Value, "rr_ttl_min", _("Domain TTL Min"),
|
||||||
_("Minimum TTL for all domain result."));
|
_("Minimum TTL for all domain result."));
|
||||||
o.rempty = true;
|
o.rempty = true;
|
||||||
o.placeholder = "300";
|
o.placeholder = "600";
|
||||||
o.default = 300;
|
o.default = 600;
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
|
||||||
// second dns server;
|
|
||||||
// rr-ttl-max;
|
// rr-ttl-max;
|
||||||
o = s.taboption("settings", form.Value, "rr_ttl_max", _("Domain TTL Max"),
|
o = s.taboption("settings", form.Value, "rr_ttl_max", _("Domain TTL Max"),
|
||||||
_("Maximum TTL for all domain result."));
|
_("Maximum TTL for all domain result."));
|
||||||
o.rempty = true;
|
o.rempty = true;
|
||||||
|
|
||||||
|
// rr-ttl-reply-max;
|
||||||
|
o = s.taboption("settings", form.Value, "rr_ttl_reply_max", _("Domain Reply TTL Max"),
|
||||||
|
_("Maximum Reply TTL for all domain result."));
|
||||||
|
o.rempty = true;
|
||||||
|
|
||||||
|
// second dns server;
|
||||||
// Eanble;
|
// Eanble;
|
||||||
o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"),
|
o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"),
|
||||||
_("Enable or disable second DNS server."));
|
_("Enable or disable second DNS server."));
|
||||||
|
|||||||
@@ -311,6 +311,9 @@ load_service()
|
|||||||
config_get rr_ttl_max "$section" "rr_ttl_max" ""
|
config_get rr_ttl_max "$section" "rr_ttl_max" ""
|
||||||
[ -z "$rr_ttl_max" ] || conf_append "rr-ttl-max" "$rr_ttl_max"
|
[ -z "$rr_ttl_max" ] || conf_append "rr-ttl-max" "$rr_ttl_max"
|
||||||
|
|
||||||
|
config_get rr_ttl_reply_max "$section" "rr_ttl_reply_max" ""
|
||||||
|
[ -z "$rr_ttl_reply_max" ] || conf_append "rr-ttl-reply-max" "$rr_ttl_reply_max"
|
||||||
|
|
||||||
config_get log_size "$section" "log_size" "64K"
|
config_get log_size "$section" "log_size" "64K"
|
||||||
[ -z "$log_size" ] || conf_append "log-size" "$log_size"
|
[ -z "$log_size" ] || conf_append "log-size" "$log_size"
|
||||||
|
|
||||||
|
|||||||
37
src/dns.h
37
src/dns.h
@@ -113,11 +113,15 @@ struct dns_head {
|
|||||||
unsigned short nrcount; /* number of addititional resource entries */
|
unsigned short nrcount; /* number of addititional resource entries */
|
||||||
} __attribute__((packed, aligned(2)));
|
} __attribute__((packed, aligned(2)));
|
||||||
|
|
||||||
struct dns_rrs {
|
#define DNS_PACKET_DICT_SIZE 16
|
||||||
unsigned short next;
|
struct dns_packet_dict_item {
|
||||||
unsigned short len;
|
unsigned pos;
|
||||||
dns_type_t type;
|
unsigned int hash;
|
||||||
unsigned char data[0];
|
};
|
||||||
|
|
||||||
|
struct dns_packet_dict {
|
||||||
|
short dict_count;
|
||||||
|
struct dns_packet_dict_item names[DNS_PACKET_DICT_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* packet haed */
|
/* packet haed */
|
||||||
@@ -130,21 +134,24 @@ struct dns_packet {
|
|||||||
unsigned short optcount;
|
unsigned short optcount;
|
||||||
unsigned short optional;
|
unsigned short optional;
|
||||||
unsigned short payloadsize;
|
unsigned short payloadsize;
|
||||||
|
struct dns_packet_dict namedict;
|
||||||
int size;
|
int size;
|
||||||
int len;
|
int len;
|
||||||
unsigned char data[0];
|
unsigned char data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* RRS encode/decode context */
|
struct dns_rrs {
|
||||||
struct dns_data_context {
|
struct dns_packet *packet;
|
||||||
unsigned char *data;
|
unsigned short next;
|
||||||
unsigned char *ptr;
|
unsigned short len;
|
||||||
unsigned int maxsize;
|
dns_type_t type;
|
||||||
|
unsigned char data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* packet encode/decode context */
|
/* packet encode/decode context */
|
||||||
struct dns_context {
|
struct dns_context {
|
||||||
struct dns_packet *packet;
|
struct dns_packet *packet;
|
||||||
|
struct dns_packet_dict *namedict;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
unsigned int maxsize;
|
unsigned int maxsize;
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
@@ -170,7 +177,7 @@ struct dns_opt_ecs {
|
|||||||
unsigned char source_prefix;
|
unsigned char source_prefix;
|
||||||
unsigned char scope_prefix;
|
unsigned char scope_prefix;
|
||||||
unsigned char addr[DNS_RR_AAAA_LEN];
|
unsigned char addr[DNS_RR_AAAA_LEN];
|
||||||
};
|
} __attribute__((packed));;
|
||||||
|
|
||||||
/* OPT COOLIE */
|
/* OPT COOLIE */
|
||||||
struct dns_opt_cookie {
|
struct dns_opt_cookie {
|
||||||
@@ -234,4 +241,12 @@ int dns_encode(unsigned char *data, int size, struct dns_packet *packet);
|
|||||||
|
|
||||||
int dns_packet_init(struct dns_packet *packet, int size, struct dns_head *head);
|
int dns_packet_init(struct dns_packet *packet, int size, struct dns_head *head);
|
||||||
|
|
||||||
|
struct dns_update_param {
|
||||||
|
int id;
|
||||||
|
int ip_ttl;
|
||||||
|
int cname_ttl;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dns_packet_update(unsigned char *data, int size, struct dns_update_param *param);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -162,6 +162,11 @@ void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, int32_t cache_flag
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dns_cache->head.is_soa = 1;
|
||||||
|
if (dns_cache->head.cache_type == CACHE_TYPE_PACKET) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache;
|
struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache;
|
||||||
if (cache_addr == NULL) {
|
if (cache_addr == NULL) {
|
||||||
goto errout;
|
goto errout;
|
||||||
@@ -229,6 +234,7 @@ struct dns_cache_data *dns_cache_new_data_packet(uint32_t cache_flag, void *pack
|
|||||||
}
|
}
|
||||||
|
|
||||||
memcpy(cache_packet->data, packet, packet_len);
|
memcpy(cache_packet->data, packet, packet_len);
|
||||||
|
memset(&cache_packet->head, 0, sizeof(cache_packet->head));
|
||||||
|
|
||||||
cache_packet->head.cache_flag = cache_flag;
|
cache_packet->head.cache_flag = cache_flag;
|
||||||
cache_packet->head.cache_type = CACHE_TYPE_PACKET;
|
cache_packet->head.cache_type = CACHE_TYPE_PACKET;
|
||||||
@@ -447,10 +453,10 @@ int dns_cache_is_soa(struct dns_cache *dns_cache)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache_get_data(dns_cache);
|
if (dns_cache->cache_data->head.is_soa) {
|
||||||
if (cache_addr->head.cache_type == CACHE_TYPE_ADDR && cache_addr->addr_data.soa) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ enum CACHE_RECORD_TYPE {
|
|||||||
struct dns_cache_data_head {
|
struct dns_cache_data_head {
|
||||||
uint32_t cache_flag;
|
uint32_t cache_flag;
|
||||||
enum CACHE_TYPE cache_type;
|
enum CACHE_TYPE cache_type;
|
||||||
|
int is_soa;
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
#define DNS_TCP_IDLE_TIMEOUT (60 * 10)
|
#define DNS_TCP_IDLE_TIMEOUT (60 * 10)
|
||||||
#define DNS_TCP_CONNECT_TIMEOUT (5)
|
#define DNS_TCP_CONNECT_TIMEOUT (5)
|
||||||
#define DNS_QUERY_TIMEOUT (500)
|
#define DNS_QUERY_TIMEOUT (500)
|
||||||
#define DNS_QUERY_RETRY (6)
|
#define DNS_QUERY_RETRY (4)
|
||||||
#define DNS_PENDING_SERVER_RETRY 40
|
#define DNS_PENDING_SERVER_RETRY 40
|
||||||
#define SOCKET_PRIORITY (6)
|
#define SOCKET_PRIORITY (6)
|
||||||
#define SOCKET_IP_TOS (IPTOS_LOWDELAY | IPTOS_RELIABILITY)
|
#define SOCKET_IP_TOS (IPTOS_LOWDELAY | IPTOS_RELIABILITY)
|
||||||
@@ -117,6 +117,7 @@ struct dns_server_info {
|
|||||||
|
|
||||||
time_t last_send;
|
time_t last_send;
|
||||||
time_t last_recv;
|
time_t last_recv;
|
||||||
|
int prohibit;
|
||||||
|
|
||||||
/* server addr info */
|
/* server addr info */
|
||||||
unsigned short ai_family;
|
unsigned short ai_family;
|
||||||
@@ -1004,6 +1005,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
|||||||
server_info->ttl = ttl;
|
server_info->ttl = ttl;
|
||||||
server_info->ttl_range = 0;
|
server_info->ttl_range = 0;
|
||||||
server_info->skip_check_cert = skip_check_cert;
|
server_info->skip_check_cert = skip_check_cert;
|
||||||
|
server_info->prohibit = 0;
|
||||||
pthread_mutex_init(&server_info->lock, NULL);
|
pthread_mutex_init(&server_info->lock, NULL);
|
||||||
memcpy(&server_info->flags, flags, sizeof(server_info->flags));
|
memcpy(&server_info->flags, flags, sizeof(server_info->flags));
|
||||||
|
|
||||||
@@ -2152,6 +2154,7 @@ static int _dns_client_process_tcp_buff(struct dns_server_info *server_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tlog(TLOG_DEBUG, "recv tcp packet from %s, len = %d", server_info->ip, len);
|
tlog(TLOG_DEBUG, "recv tcp packet from %s, len = %d", server_info->ip, len);
|
||||||
|
time(&server_info->last_recv);
|
||||||
/* process result */
|
/* process result */
|
||||||
if (_dns_client_recv(server_info, inpacket_data, dns_packet_len, &server_info->addr, server_info->ai_addrlen) !=
|
if (_dns_client_recv(server_info, inpacket_data, dns_packet_len, &server_info->addr, server_info->ai_addrlen) !=
|
||||||
0) {
|
0) {
|
||||||
@@ -2230,7 +2233,6 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
time(&server_info->last_recv);
|
|
||||||
server_info->recv_buff.len += len;
|
server_info->recv_buff.len += len;
|
||||||
if (server_info->recv_buff.len <= 2) {
|
if (server_info->recv_buff.len <= 2) {
|
||||||
/* wait and recv */
|
/* wait and recv */
|
||||||
@@ -2787,6 +2789,14 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
|||||||
list_for_each_entry_safe(group_member, tmp, &query->server_group->head, list)
|
list_for_each_entry_safe(group_member, tmp, &query->server_group->head, list)
|
||||||
{
|
{
|
||||||
server_info = group_member->server;
|
server_info = group_member->server;
|
||||||
|
if (server_info->prohibit) {
|
||||||
|
time_t now;
|
||||||
|
time(&now);
|
||||||
|
if ((now - 60 < server_info->last_send) && (now - 5 > server_info->last_recv)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
server_info->prohibit = 0;
|
||||||
|
}
|
||||||
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);
|
||||||
if (server_info->fd <= 0) {
|
if (server_info->fd <= 0) {
|
||||||
@@ -2838,6 +2848,8 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
|||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
if (now - 5 > server_info->last_recv || send_err != ENOMEM) {
|
if (now - 5 > server_info->last_recv || send_err != ENOMEM) {
|
||||||
|
server_info->prohibit = 1;
|
||||||
|
tlog(TLOG_INFO, "server %s not alive, prohibit", server_info->ip);
|
||||||
_dns_client_shutdown_socket(server_info);
|
_dns_client_shutdown_socket(server_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3261,6 +3273,34 @@ static void *_dns_client_work(void *arg)
|
|||||||
|
|
||||||
int dns_client_set_ecs(char *ip, int subnet)
|
int dns_client_set_ecs(char *ip, int subnet)
|
||||||
{
|
{
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
socklen_t addr_len = sizeof(addr);
|
||||||
|
getaddr_by_host(ip, (struct sockaddr *)&addr, &addr_len);
|
||||||
|
|
||||||
|
switch (addr.ss_family) {
|
||||||
|
case AF_INET: {
|
||||||
|
struct sockaddr_in *addr_in;
|
||||||
|
addr_in = (struct sockaddr_in *)&addr;
|
||||||
|
memcpy(&client.ecs_ipv4.ipv4_addr, &addr_in->sin_addr.s_addr, 4);
|
||||||
|
client.ecs_ipv4.bitlen = subnet;
|
||||||
|
client.ecs_ipv4.enable = 1;
|
||||||
|
} break;
|
||||||
|
case AF_INET6: {
|
||||||
|
struct sockaddr_in6 *addr_in6;
|
||||||
|
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||||
|
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||||
|
memcpy(&client.ecs_ipv4.ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4);
|
||||||
|
client.ecs_ipv4.bitlen = subnet;
|
||||||
|
client.ecs_ipv4.enable = 1;
|
||||||
|
} else {
|
||||||
|
memcpy(&client.ecs_ipv6.ipv6_addr, addr_in6->sin6_addr.s6_addr, 16);
|
||||||
|
client.ecs_ipv6.bitlen = subnet;
|
||||||
|
client.ecs_ipv6.enable = 1;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ int dns_conf_tcp_idle_time = 120;
|
|||||||
/* cache */
|
/* cache */
|
||||||
int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
|
int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
|
||||||
int dns_conf_prefetch = 0;
|
int dns_conf_prefetch = 0;
|
||||||
int dns_conf_serve_expired = 0;
|
int dns_conf_serve_expired = 1;
|
||||||
int dns_conf_serve_expired_ttl = 0;
|
int dns_conf_serve_expired_ttl = 0;
|
||||||
int dns_conf_serve_expired_reply_ttl = 5;
|
int dns_conf_serve_expired_reply_ttl = 5;
|
||||||
|
|
||||||
@@ -90,12 +90,13 @@ art_tree dns_conf_domain_rule;
|
|||||||
struct dns_conf_address_rule dns_conf_address_rule;
|
struct dns_conf_address_rule dns_conf_address_rule;
|
||||||
|
|
||||||
/* dual-stack selection */
|
/* dual-stack selection */
|
||||||
int dns_conf_dualstack_ip_selection;
|
int dns_conf_dualstack_ip_selection = 1;
|
||||||
int dns_conf_dualstack_ip_selection_threshold = 30;
|
int dns_conf_dualstack_ip_selection_threshold = 15;
|
||||||
|
|
||||||
/* TTL */
|
/* TTL */
|
||||||
int dns_conf_rr_ttl;
|
int dns_conf_rr_ttl;
|
||||||
int dns_conf_rr_ttl_min;
|
int dns_conf_rr_ttl_reply_max;
|
||||||
|
int dns_conf_rr_ttl_min = 600;
|
||||||
int dns_conf_rr_ttl_max;
|
int dns_conf_rr_ttl_max;
|
||||||
int dns_conf_force_AAAA_SOA;
|
int dns_conf_force_AAAA_SOA;
|
||||||
|
|
||||||
@@ -1176,11 +1177,13 @@ static int _config_iplist_rule(char *subnet, enum address_rule rule)
|
|||||||
static int _config_qtype_soa(void *data, int argc, char *argv[])
|
static int _config_qtype_soa(void *data, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct dns_qtype_soa_list *soa_list;
|
struct dns_qtype_soa_list *soa_list;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
soa_list = malloc(sizeof(*soa_list));
|
soa_list = malloc(sizeof(*soa_list));
|
||||||
if (soa_list == NULL) {
|
if (soa_list == NULL) {
|
||||||
tlog(TLOG_ERROR, "cannot malloc memory");
|
tlog(TLOG_ERROR, "cannot malloc memory");
|
||||||
@@ -1254,7 +1257,7 @@ static int _conf_edns_client_subnet(void *data, int argc, char *argv[])
|
|||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
socklen_t addr_len = sizeof(addr);
|
socklen_t addr_len = sizeof(addr);
|
||||||
|
|
||||||
if (argc <= 1 || data == NULL) {
|
if (argc <= 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1485,6 +1488,7 @@ static struct config_item _config_item[] = {
|
|||||||
CONF_INT("rr-ttl", &dns_conf_rr_ttl, 0, CONF_INT_MAX),
|
CONF_INT("rr-ttl", &dns_conf_rr_ttl, 0, CONF_INT_MAX),
|
||||||
CONF_INT("rr-ttl-min", &dns_conf_rr_ttl_min, 0, CONF_INT_MAX),
|
CONF_INT("rr-ttl-min", &dns_conf_rr_ttl_min, 0, CONF_INT_MAX),
|
||||||
CONF_INT("rr-ttl-max", &dns_conf_rr_ttl_max, 0, CONF_INT_MAX),
|
CONF_INT("rr-ttl-max", &dns_conf_rr_ttl_max, 0, CONF_INT_MAX),
|
||||||
|
CONF_INT("rr-ttl-reply-max", &dns_conf_rr_ttl_reply_max, 0, CONF_INT_MAX),
|
||||||
CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA),
|
CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA),
|
||||||
CONF_CUSTOM("force-qtype-SOA", _config_qtype_soa, NULL),
|
CONF_CUSTOM("force-qtype-SOA", _config_qtype_soa, NULL),
|
||||||
CONF_CUSTOM("blacklist-ip", _config_blacklist_ip, NULL),
|
CONF_CUSTOM("blacklist-ip", _config_blacklist_ip, NULL),
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ extern int dns_conf_dualstack_ip_selection;
|
|||||||
extern int dns_conf_dualstack_ip_selection_threshold;
|
extern int dns_conf_dualstack_ip_selection_threshold;
|
||||||
|
|
||||||
extern int dns_conf_rr_ttl;
|
extern int dns_conf_rr_ttl;
|
||||||
|
extern int dns_conf_rr_ttl_reply_max;
|
||||||
extern int dns_conf_rr_ttl_min;
|
extern int dns_conf_rr_ttl_min;
|
||||||
extern int dns_conf_rr_ttl_max;
|
extern int dns_conf_rr_ttl_max;
|
||||||
extern int dns_conf_force_AAAA_SOA;
|
extern int dns_conf_force_AAAA_SOA;
|
||||||
|
|||||||
1553
src/dns_server.c
1553
src/dns_server.c
File diff suppressed because it is too large
Load Diff
@@ -1049,6 +1049,7 @@ void print_stack(void)
|
|||||||
{
|
{
|
||||||
const size_t max_buffer = 30;
|
const size_t max_buffer = 30;
|
||||||
void *buffer[max_buffer];
|
void *buffer[max_buffer];
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
struct backtrace_state state = {buffer, buffer + max_buffer};
|
struct backtrace_state state = {buffer, buffer + max_buffer};
|
||||||
_Unwind_Backtrace(unwind_callback, &state);
|
_Unwind_Backtrace(unwind_callback, &state);
|
||||||
@@ -1058,7 +1059,7 @@ void print_stack(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tlog(TLOG_FATAL, "Stack:");
|
tlog(TLOG_FATAL, "Stack:");
|
||||||
for (int idx = 0; idx < frame_num; ++idx) {
|
for (idx = 0; idx < frame_num; ++idx) {
|
||||||
const void *addr = buffer[idx];
|
const void *addr = buffer[idx];
|
||||||
const char *symbol = "";
|
const char *symbol = "";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user