From c561ae2fc53251d15c114b76f8212eb1afd24ea6 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Fri, 29 Apr 2022 22:29:40 +0800 Subject: [PATCH] Feature: Supports setting the maximum TTL value of the response to the client --- ReadMe.md | 1 + ReadMe_en.md | 1 + etc/smartdns/smartdns.conf | 2 ++ .../files/luci/i18n/smartdns.zh-cn.po | 3 +++ .../luci/model/cbi/smartdns/smartdns.lua | 6 ++++- .../luci/files/luci/i18n/smartdns.zh-cn.po | 3 +++ .../resources/view/smartdns/smartdns.js | 9 +++++-- package/openwrt/files/etc/init.d/smartdns | 3 +++ src/dns_conf.c | 2 ++ src/dns_conf.h | 1 + src/dns_server.c | 26 ++++++++++++++++--- 11 files changed, 51 insertions(+), 6 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index b7e4f03..75b0898 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -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-min` | 允许的最小 TTL 值 | 远程查询结果 | 大于 `0` 的数字 | `rr-ttl-min 60` | | `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-file` | 日志文件路径 | `/var/log/smartdns.log` | 合法路径字符串 | `log-file /var/log/smartdns.log` | | `log-size` | 日志大小 | `128K` | 数字 + `K`、`M` 或 `G` | `log-size 128K` | diff --git a/ReadMe_en.md b/ReadMe_en.md index 405be08..74cfef3 100755 --- a/ReadMe_en.md +++ b/ReadMe_en.md @@ -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 |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-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 |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 diff --git a/etc/smartdns/smartdns.conf b/etc/smartdns/smartdns.conf index d950e74..3b6547a 100644 --- a/etc/smartdns/smartdns.conf +++ b/etc/smartdns/smartdns.conf @@ -102,10 +102,12 @@ cache-size 4096 # rr-ttl: ttl for all record # rr-ttl-min: minimum ttl for resource record # rr-ttl-max: maximum ttl for resource record +# tr-ttl-reply-max: maximum reply ttl for resource record # example: # rr-ttl 300 # rr-ttl-min 60 # rr-ttl-max 86400 +# rr-ttl-reply-max 60 # set log level # log-level: [level], level=fatal, error, warn, notice, info, debug diff --git a/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po b/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po index d45b771..53ae707 100644 --- a/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po +++ b/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po @@ -124,6 +124,9 @@ msgstr "域名TTL最大值" msgid "Maximum TTL for all domain result." msgstr "设置所有域名的TTL最大值" +msgid "Maximum Reply TTL for all domain result." +msgstr "设置返回给客户端的TTL最大值" + msgid "smartdns custom settings" msgstr "smartdns 自定义设置,具体配置参数参考指导" diff --git a/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua b/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua index 4bcaf88..6decff0 100644 --- a/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua +++ b/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua @@ -116,11 +116,15 @@ o.placeholder = "600" o.default = 600 o.optional = true ----- second dns server ---- rr-ttl-max o = s:taboption("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result.")) 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 o = s:taboption("seconddns", Flag, "seconddns_enabled", translate("Enable"), translate("Enable or disable second DNS server.")) o.default = o.disabled diff --git a/package/luci/files/luci/i18n/smartdns.zh-cn.po b/package/luci/files/luci/i18n/smartdns.zh-cn.po index 331b432..6a5a165 100644 --- a/package/luci/files/luci/i18n/smartdns.zh-cn.po +++ b/package/luci/files/luci/i18n/smartdns.zh-cn.po @@ -130,6 +130,9 @@ msgstr "域名TTL最大值" msgid "Maximum TTL for all domain result." msgstr "设置所有域名的TTL最大值" +msgid "Maximum Reply TTL for all domain result." +msgstr "设置返回给客户端的TTL最大值" + msgid "smartdns custom settings" msgstr "smartdns 自定义设置,具体配置参数参考指导" diff --git a/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js b/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js index b385115..7d5224b 100644 --- a/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js +++ b/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js @@ -227,12 +227,17 @@ return L.view.extend({ o.default = 600; o.optional = true; - // second dns server; // rr-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; + // 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; o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"), _("Enable or disable second DNS server.")); diff --git a/package/openwrt/files/etc/init.d/smartdns b/package/openwrt/files/etc/init.d/smartdns index 2bf799e..af0638e 100644 --- a/package/openwrt/files/etc/init.d/smartdns +++ b/package/openwrt/files/etc/init.d/smartdns @@ -311,6 +311,9 @@ load_service() config_get rr_ttl_max "$section" "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" [ -z "$log_size" ] || conf_append "log-size" "$log_size" diff --git a/src/dns_conf.c b/src/dns_conf.c index ca72b63..40fdafc 100644 --- a/src/dns_conf.c +++ b/src/dns_conf.c @@ -95,6 +95,7 @@ int dns_conf_dualstack_ip_selection_threshold = 15; /* TTL */ int dns_conf_rr_ttl; +int dns_conf_rr_ttl_rely_max = 60; int dns_conf_rr_ttl_min = 600; int dns_conf_rr_ttl_max; int dns_conf_force_AAAA_SOA; @@ -1487,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-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-reply-max", &dns_conf_rr_ttl_rely_max, 0, CONF_INT_MAX), CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA), CONF_CUSTOM("force-qtype-SOA", _config_qtype_soa, NULL), CONF_CUSTOM("blacklist-ip", _config_blacklist_ip, NULL), diff --git a/src/dns_conf.h b/src/dns_conf.h index bc77bee..534aada 100644 --- a/src/dns_conf.h +++ b/src/dns_conf.h @@ -255,6 +255,7 @@ extern int dns_conf_dualstack_ip_selection; extern int dns_conf_dualstack_ip_selection_threshold; extern int dns_conf_rr_ttl; +extern int dns_conf_rr_ttl_rely_max; extern int dns_conf_rr_ttl_min; extern int dns_conf_rr_ttl_max; extern int dns_conf_force_AAAA_SOA; diff --git a/src/dns_server.c b/src/dns_server.c index 805abdd..5877cb9 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -1082,6 +1082,17 @@ static int _dns_request_post(struct dns_server_post_context *context) /* log audit log */ _dns_server_audit_log(context); + + if (context->reply_ttl > 0) { + struct dns_update_param param; + param.id = request->id; + param.ip_ttl = context->reply_ttl; + if (dns_packet_update(context->inpacket, context->inpacket_len, ¶m) != 0) { + tlog(TLOG_ERROR, "update packet info failed."); + return -1; + } + } + ret = _dns_reply_inpacket(request, context->inpacket, context->inpacket_len); if (ret != 0) { tlog(TLOG_ERROR, "replay raw packet to client failed."); @@ -1304,6 +1315,7 @@ out: context.do_force_soa = force_A; context.do_audit = 1; context.do_reply = 1; + context.reply_ttl = dns_conf_rr_ttl_rely_max; context.skip_notify_count = 1; _dns_request_post(&context); @@ -2299,7 +2311,6 @@ static int _dns_server_reply_passthrouth(struct dns_server_post_context *context if (request->conn && context->do_reply == 1) { /* When passthrough, modify the id to be the id of the client request. */ - dns_server_update_reply_packet_id(request, context->inpacket, context->inpacket_len); struct dns_update_param param; param.id = request->id; param.ip_ttl = context->reply_ttl; @@ -2339,7 +2350,7 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, unsi context.do_audit = 1; context.do_reply = 1; context.do_ipset = 1; - context.reply_ttl = -1; + context.reply_ttl = dns_conf_rr_ttl_rely_max; return _dns_server_reply_passthrouth(&context); } _dns_server_process_answer(request, domain, packet, result_flag); @@ -2731,7 +2742,16 @@ static int _dns_server_get_expired_ttl_reply(struct dns_cache *dns_cache) { int ttl = dns_cache_get_ttl(dns_cache); if (ttl > 0) { - return ttl; + int ttl_reply = 0; + if (dns_conf_rr_ttl_rely_max > 0) { + ttl_reply = ttl % dns_conf_rr_ttl_rely_max; + } + + if (ttl_reply == 0) { + ttl_reply = (ttl > dns_conf_rr_ttl_rely_max) ? dns_conf_rr_ttl_rely_max : ttl; + } + + return ttl_reply; } return dns_conf_serve_expired_reply_ttl;