From 9398573e6f1765c6186a068c010942135af8005a Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Tue, 25 Dec 2018 01:55:37 +0800 Subject: [PATCH] Add luci for new feature, and fix some bugs --- etc/smartdns/smartdns.conf | 10 +++--- .../luci/files/luci/controller/smartdns.lua | 4 ++- .../luci/files/luci/i18n/smartdns.zh-cn.po | 9 +++++ .../model/cbi/{ => smartdns}/smartdns.lua | 25 +++++++++----- .../luci/model/cbi/smartdns/upstream.lua | 24 ++++++++++++++ package/openwrt/files/etc/init.d/smartdns | 33 +++++++++++++++---- package/optware/S50smartdns | 13 ++++++-- src/dns_conf.c | 8 ++--- src/dns_conf.h | 4 +-- src/dns_server.c | 20 ++++++----- 10 files changed, 114 insertions(+), 36 deletions(-) rename package/luci/files/luci/model/cbi/{ => smartdns}/smartdns.lua (92%) create mode 100644 package/luci/files/luci/model/cbi/smartdns/upstream.lua diff --git a/etc/smartdns/smartdns.conf b/etc/smartdns/smartdns.conf index 8cd51bd..12c23f4 100644 --- a/etc/smartdns/smartdns.conf +++ b/etc/smartdns/smartdns.conf @@ -39,10 +39,10 @@ cache-size 512 # force AAAA query return SOA # force-AAAA-SOA [yes|no] -# enabel ipv4 and ipv6 preference -# dualstack-preference-threshold [num] (100~10000) -# dualstack-preference [yes|no] -# dualstack-preference yes +# Enable IPV4, IPV6 dual stack IP optimization selection strategy +# dualstack-ip-selection-threshold [num] (1~1000) +# dualstack-ip-selection [yes|no] +# dualstack-ip-selection yes # edns client subnet # edns-client-subnet-ipv4 [ip/subnet] @@ -80,7 +80,7 @@ log-level info # default port is 53 # -blacklist-ip: filter result with blacklist ip # -check-edns: result must exist edns RR, or discard result. -# -check-ttl: Check whether TTL is the corresponding value, or discard result, -check-ttl=0 for auto check TTL. +# -check-ttl: Check whether the TTL of result is equal, If not equal, discard the result, -check-ttl=0 for auto check TTL. # server 8.8.8.8 -blacklist-ip -check-edns # remote tcp dns server list diff --git a/package/luci/files/luci/controller/smartdns.lua b/package/luci/files/luci/controller/smartdns.lua index c3f0e86..8248d41 100644 --- a/package/luci/files/luci/controller/smartdns.lua +++ b/package/luci/files/luci/controller/smartdns.lua @@ -9,10 +9,12 @@ function index() end local page - page = entry({"admin", "services", "smartdns"}, cbi("smartdns"), _("SmartDNS"), 60) + page = entry({"admin", "services", "smartdns"}, cbi("smartdns/smartdns"), _("SmartDNS"), 60) page.dependent = true page = entry({"admin", "services", "smartdns", "status"}, call("act_status")) page.leaf = true + page = entry({"admin", "services", "smartdns", "upstream"}, cbi("smartdns/upstream"), nil) + page.leaf = true end local function is_running() diff --git a/package/luci/files/luci/i18n/smartdns.zh-cn.po b/package/luci/files/luci/i18n/smartdns.zh-cn.po index ef4affb..8cbbbab 100644 --- a/package/luci/files/luci/i18n/smartdns.zh-cn.po +++ b/package/luci/files/luci/i18n/smartdns.zh-cn.po @@ -55,6 +55,12 @@ msgstr "IPV6服务器" msgid "Enable IPV6 DNS Server" msgstr "启用IPV6服务器" +msgid "Dual-stack IP Selection" +msgstr "双栈IP优选" + +msgid "Enable IP selection between IPV4 and IPV6" +msgstr "启用或禁用IPV4,IPV6间的IP优选策略。" + msgid "Redirect" msgstr "重定向" @@ -127,6 +133,9 @@ msgstr "IP黑名单过滤" msgid "Filtering IP with blacklist" msgstr "使用IP黑名单过滤" +msgid "Upstream DNS Server Configuration" +msgstr "上游DNS服务器配置" + msgid "Set Specific domain ip address." msgstr "指定特定域名的IP地址" diff --git a/package/luci/files/luci/model/cbi/smartdns.lua b/package/luci/files/luci/model/cbi/smartdns/smartdns.lua similarity index 92% rename from package/luci/files/luci/model/cbi/smartdns.lua rename to package/luci/files/luci/model/cbi/smartdns/smartdns.lua index e0e774b..6e27728 100644 --- a/package/luci/files/luci/model/cbi/smartdns.lua +++ b/package/luci/files/luci/model/cbi/smartdns/smartdns.lua @@ -52,6 +52,14 @@ o.cfgvalue = function(...) return Flag.cfgvalue(...) or "1" end +---- 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.rmempty = false +o.default = o.disabled +o.cfgvalue = function(...) + return Flag.cfgvalue(...) or "0" +end + ---- Redirect o = s:taboption("settings", ListValue, "redirect", translate("Redirect"), translate("SmartDNS redirect mode")) o.placeholder = "none" @@ -102,6 +110,15 @@ s = m:section(TypedSection, "server", translate("Upstream Servers"), translate(" s.anonymous = true s.addremove = true s.template = "cbi/tblsection" +s.extedit = luci.dispatcher.build_url("admin/services/smartdns/upstream/%s") + +---- enable flag +o = s:option(Flag, "enabled", translate("Enable"), translate("Enable")) +o.rmempty = false +o.default = o.enabled +o.cfgvalue = function(...) + return Flag.cfgvalue(...) or "1" +end ---- name s:option(Value, "name", translate("Name"), translate("DNS Server name")) @@ -124,14 +141,6 @@ o:value("tls", translate("tls")) o.default = "udp" o.rempty = false ----- blacklist_ip -o = s:option(Flag, "blacklist_ip", translate("IP Blacklist Filtering"), translate("Filtering IP with blacklist")) -o.rmempty = false -o.default = o.disabled -o.cfgvalue = function(...) - return Flag.cfgvalue(...) or "0" -end - -- Doman addresss s = m:section(TypedSection, "smartdns", translate("Domain Address"), translate("Set Specific domain ip address.")) diff --git a/package/luci/files/luci/model/cbi/smartdns/upstream.lua b/package/luci/files/luci/model/cbi/smartdns/upstream.lua new file mode 100644 index 0000000..451f61b --- /dev/null +++ b/package/luci/files/luci/model/cbi/smartdns/upstream.lua @@ -0,0 +1,24 @@ +local sid = arg[1] + +m = Map("smartdns", "%s - %s" %{translate("SmartDNS Server"), translate("Upstream DNS Server Configuration")}) +m.redirect = luci.dispatcher.build_url("admin/services/smartdns") + +if m.uci:get("smartdns", sid) ~= "server" then + luci.http.redirect(m.redirect) + return +end + +-- [[ Edit Server ]]-- +s = m:section(NamedSection, sid, "server") +s.anonymous = true +s.addremove = false + +---- blacklist_ip +o = s:option(Flag, "blacklist_ip", translate("IP Blacklist Filtering"), translate("Filtering IP with blacklist")) +o.rmempty = false +o.default = o.disabled +o.cfgvalue = function(...) + return Flag.cfgvalue(...) or "0" +end + +return m \ No newline at end of file diff --git a/package/openwrt/files/etc/init.d/smartdns b/package/openwrt/files/etc/init.d/smartdns index adb794c..da2cabe 100644 --- a/package/openwrt/files/etc/init.d/smartdns +++ b/package/openwrt/files/etc/init.d/smartdns @@ -113,11 +113,16 @@ load_server() { local section="$1" local ADDITIONAL_ARGS="" + config_get_bool "enabled" "$section" "enabled" "1" config_get "port" "$section" "port" "53" config_get "type" "$section" "type" "udp" config_get "ip" "$section" "ip" "" config_get "blacklist_ip" "$section" "blacklist_ip" "0" + if [ "$enabled" = "0" ]; then + return + fi + if [ -z "$port" ] || [ -z "$ip" ] || [ -z "$type" ]; then return fi @@ -167,6 +172,11 @@ start_service() { conf_append "bind-tcp" ":$port" fi fi + config_get "dualstack_ip_selection" "$section" "dualstack_ip_selection" "0" + if [ "$dualstack_ip_selection" = "1" ]; then + conf_append "dualstack-ip-selection" "yes" + fi + SMARTDNS_PORT="$port" mkdir -p $SMARTDNS_CONF_DIR @@ -215,15 +225,26 @@ start_service() { config_get "old_redirect" "$section" "old_redirect" "none" config_get "old_port" "$section" "old_port" "0" - if [ "$old_redirect" != "none" ] && [ "$old_port" != "0" ]; then + if [ "$old_port" != "$SMARTDNS_PORT" ]; then clear_iptable "$old_port" "$ipv6_server" - stop_forward_dnsmasq "$old_port" + if [ "$redirect" = "redirect" ]; then + set_iptable $ipv6_server $tcp_server + fi fi - if [ "$redirect" = "redirect" ]; then - set_iptable $ipv6_server $tcp_server - elif [ "$redirect" = "dnsmasq-upstream" ]; then - set_forward_dnsmasq "$SMARTDNS_PORT" + if [ "$old_redirect" != "$redirect" ]; then + if [ "$old_redirect" != "none" ]; then + if [ "$old_port" != "0" ]; then + clear_iptable "$old_port" "$ipv6_server" + fi + stop_forward_dnsmasq "$old_port" + fi + + if [ "$redirect" = "redirect" ]; then + set_iptable $ipv6_server $tcp_server + elif [ "$redirect" = "dnsmasq-upstream" ]; then + set_forward_dnsmasq "$SMARTDNS_PORT" + fi fi uci delete smartdns.@smartdns[0].old_redirect 2>/dev/null diff --git a/package/optware/S50smartdns b/package/optware/S50smartdns index ad4522a..b7365d6 100644 --- a/package/optware/S50smartdns +++ b/package/optware/S50smartdns @@ -51,7 +51,7 @@ case "$1" in fi ;; status) - pid="`cat $SMARTDNS_PID 2>/dev/null`" + pid="`cat $SMARTDNS_PID |head -n 1 2>/dev/null`" if [ -z "$pid" ]; then echo "smartdns not running." return 0 @@ -66,7 +66,16 @@ case "$1" in ;; stop) clear_iptable - pid="`cat $SMARTDNS_PID 2>/dev/null`" + pid="`cat $SMARTDNS_PID | head -n 1 2>/dev/null`" + if [ -z "$pid" ]; then + echo "smartdns not running." + return 0 + fi + + if [ ! -d "/proc/$pid" ]; then + return 0; + fi + kill -9 $pid 2>/dev/null ;; force-reload|restart) diff --git a/src/dns_conf.c b/src/dns_conf.c index 2217d81..b7a99f9 100644 --- a/src/dns_conf.c +++ b/src/dns_conf.c @@ -36,8 +36,8 @@ int dns_conf_audit_num = 2; art_tree dns_conf_domain_rule; radix_tree_t *dns_conf_address_rule; -int dns_conf_dualstack_preference; -int dns_conf_dualstack_threshold = 1000; // cent usecond +int dns_conf_dualstack_ip_selection; +int dns_conf_dualstack_ip_selection_threshold = 100; int dns_conf_rr_ttl; int dns_conf_rr_ttl_min; @@ -582,8 +582,8 @@ struct config_item config_item[] = { CONF_INT("tcp-idle-time", &dns_conf_tcp_idle_time, 0, 3600), CONF_INT("cache-size", &dns_conf_cachesize, 0, CONF_INT_MAX), CONF_YESNO("prefetch-domain", &dns_conf_prefetch), - CONF_YESNO("dualstack-preference", &dns_conf_dualstack_preference), - CONF_INT("dualstack-preference-threshold", &dns_conf_dualstack_threshold, 100, 10000), + CONF_YESNO("dualstack-ip-selection", &dns_conf_dualstack_ip_selection), + CONF_INT("dualstack-ip-selection-threshold", &dns_conf_dualstack_ip_selection_threshold, 1, 1000), CONF_CUSTOM("log-level", config_log_level, NULL), CONF_STRING("log-file", (char *)dns_conf_log_file, DNS_MAX_PATH), CONF_SIZE("log-size", &dns_conf_log_size, 0, 1024 * 1024 * 1024), diff --git a/src/dns_conf.h b/src/dns_conf.h index 1798c3f..4e06265 100644 --- a/src/dns_conf.h +++ b/src/dns_conf.h @@ -106,8 +106,8 @@ extern char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN]; extern art_tree dns_conf_domain_rule; extern radix_tree_t *dns_conf_address_rule; -extern int dns_conf_dualstack_preference; -extern int dns_conf_dualstack_threshold; +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_min; diff --git a/src/dns_server.c b/src/dns_server.c index 42ce90b..a696045 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -521,7 +521,7 @@ int _dns_server_request_complete(struct dns_request *request) if (request->has_ipv4) { dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v4, DNS_T_AAAA, request->ipv4_addr, DNS_RR_A_LEN); - if ((request->ping_ttl_v4 - dns_conf_dualstack_threshold < request->ping_ttl_v6 ) && (request->ping_ttl_v4 > 0)) { + if (((request->ping_ttl_v4 + (dns_conf_dualstack_ip_selection_threshold * 10) < request->ping_ttl_v6 ) && (request->ping_ttl_v4 > 0)) || (request->ping_ttl_v6 == -1) ) { tlog(TLOG_DEBUG, "Force IPV4 perfered."); return _dns_server_reply_SOA(DNS_RC_NOERROR, request, NULL); } @@ -679,8 +679,8 @@ void _dns_server_ping_result(struct ping_host_struct *ping_host, const char *hos memcpy(request->ipv4_addr, &addr_in->sin_addr.s_addr, 4); } - if (dns_conf_dualstack_preference == 1 && request->qtype == DNS_T_AAAA) { - threshold = dns_conf_dualstack_threshold; + if (dns_conf_dualstack_ip_selection == 1 && request->qtype == DNS_T_AAAA) { + threshold = dns_conf_dualstack_ip_selection_threshold * 10; } } break; case AF_INET6: { @@ -861,7 +861,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain, unsigned char addr[4]; if (request->qtype != DNS_T_A) { /* ignore non-matched query type */ - if (dns_conf_dualstack_preference == 0) { + if (dns_conf_dualstack_ip_selection == 0) { break; } } @@ -1033,6 +1033,7 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, unsi /* Not need to wait check result if only has one ip address */ if (ip_num == 1 && request_wait == 1) { _dns_server_request_complete(request); + _dns_server_request_remove(request); } if (request->has_ipv4 == 0 && request->has_ipv6 == 0) { @@ -1363,7 +1364,7 @@ static int _dns_server_recv(struct dns_server_conn *client, unsigned char *inpac request->request_wait++; dns_client_query(request->domain, qtype, dns_server_resolve_callback, request); - if (qtype == DNS_T_AAAA && dns_conf_dualstack_preference) { + if (qtype == DNS_T_AAAA && dns_conf_dualstack_ip_selection) { _dns_server_request_get(request); request->request_wait++; dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request); @@ -1545,10 +1546,12 @@ int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver) int total_len = dnsserver->recvbuff.size; int proceed_len = 0; unsigned char *request_data = NULL; + int ret = 0; for (;;) { if ((total_len - proceed_len) <= sizeof(unsigned short)) { - return 1; + ret = 1; + break; } request_len = ntohs(*((unsigned short *)(dnsserver->recvbuff.buf + proceed_len))); @@ -1559,7 +1562,8 @@ int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver) } if (request_len > (total_len - proceed_len)) { - return 1; + ret = 1; + break; } request_data = (unsigned char *)(dnsserver->recvbuff.buf + proceed_len + sizeof(unsigned short)); @@ -1578,7 +1582,7 @@ int _dns_server_tcp_process_one_request(struct dns_server_conn *dnsserver) dnsserver->recvbuff.size -= proceed_len; - return 0; + return ret; } int _dns_server_tcp_process_requests(struct dns_server_conn *client)