Compare commits

...

16 Commits

Author SHA1 Message Date
Nick Peng
34691154fb passthrouth: fix passthrouth ttl 2022-05-03 10:25:33 +08:00
Nick Peng
29a5803860 Fix typo & ttl issue. 2022-05-03 09:00:30 +08:00
Nick Peng
ebd820bcbb dns_server: make max ttl no countdown 2022-05-02 22:53:51 +08:00
Nick Peng
1de5557430 client: support ECS 2022-04-30 20:22:57 +08:00
Nick Peng
c92615e6cd dual-stack: return soa when ipv4 exists in cache 2022-04-30 08:46:30 +08:00
Nick Peng
c561ae2fc5 Feature: Supports setting the maximum TTL value of the response to the client 2022-04-29 22:29:40 +08:00
Nick Peng
d30264ed08 script: force stop smartdns process 2022-04-29 10:09:40 +08:00
Nick Peng
22e13b40db dns_server: fix passthrouth ipset issue 2022-04-26 20:43:11 +08:00
Nick Peng
75dda9340d dns_conf: update default configuration. 2022-04-25 18:46:52 +08:00
Nick Peng
baf2be681d dns-server: Parallel query performance optimization for the same domain name 2022-04-25 18:46:40 +08:00
Nick Peng
5bd521c36b dns_server: Cache A record for AAAA query when dualstack select 2022-04-22 23:36:37 +08:00
Nick Peng
d0305f60f6 dns_server: make fastest ip first place & fix audit log and ipset for multi IPs. 2022-04-17 18:03:24 +08:00
Nick Peng
6e1363dca4 Feature: select all best ip 2022-04-10 19:47:00 +08:00
Nick Peng
23e9021d30 client: avoid retry query storm 2022-04-09 11:12:00 +08:00
Nick Peng
92af4c05c0 dns: support domain compress. 2022-04-05 21:21:33 +08:00
Nick Peng
24661c2419 Fix issue #903 TXT, SRV, record failed. 2022-04-04 10:34:55 +08:00
18 changed files with 1678 additions and 977 deletions

View File

@@ -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` |

View File

@@ -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|second0disable> 0 seconds after expiration|serve-expired-ttl 0 |serve-expired-ttl|Cache serve expired limite TTL|0|second0disable> 0 seconds after expiration|serve-expired-ttl 0
|serve-expired-reply-ttl|TTL value to use when replying with expired data|5|second0disable> 0 seconds after expiration|serve-expired-reply-ttl 30 |serve-expired-reply-ttl|TTL value to use when replying with expired data|5|second0disable> 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

View File

@@ -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)"

View File

@@ -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

View File

@@ -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 自定义设置,具体配置参数参考指导"

View File

@@ -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

View File

@@ -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 自定义设置,具体配置参数参考指导"

View File

@@ -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."));

View File

@@ -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"

909
src/dns.c

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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;
} }

View File

@@ -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;
}; };

View File

@@ -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;
} }

View File

@@ -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),

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -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 = "";