Add luci for new feature, and fix some bugs

This commit is contained in:
Nick Peng
2018-12-25 01:55:37 +08:00
parent 11552f906f
commit 9398573e6f
10 changed files with 114 additions and 36 deletions

View File

@@ -39,10 +39,10 @@ cache-size 512
# force AAAA query return SOA # force AAAA query return SOA
# force-AAAA-SOA [yes|no] # force-AAAA-SOA [yes|no]
# enabel ipv4 and ipv6 preference # Enable IPV4, IPV6 dual stack IP optimization selection strategy
# dualstack-preference-threshold [num] (100~10000) # dualstack-ip-selection-threshold [num] (1~1000)
# dualstack-preference [yes|no] # dualstack-ip-selection [yes|no]
# dualstack-preference yes # dualstack-ip-selection yes
# edns client subnet # edns client subnet
# edns-client-subnet-ipv4 [ip/subnet] # edns-client-subnet-ipv4 [ip/subnet]
@@ -80,7 +80,7 @@ log-level info
# default port is 53 # default port is 53
# -blacklist-ip: filter result with blacklist ip # -blacklist-ip: filter result with blacklist ip
# -check-edns: result must exist edns RR, or discard result. # -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 # server 8.8.8.8 -blacklist-ip -check-edns
# remote tcp dns server list # remote tcp dns server list

View File

@@ -9,10 +9,12 @@ function index()
end end
local page 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.dependent = true
page = entry({"admin", "services", "smartdns", "status"}, call("act_status")) page = entry({"admin", "services", "smartdns", "status"}, call("act_status"))
page.leaf = true page.leaf = true
page = entry({"admin", "services", "smartdns", "upstream"}, cbi("smartdns/upstream"), nil)
page.leaf = true
end end
local function is_running() local function is_running()

View File

@@ -55,6 +55,12 @@ msgstr "IPV6服务器"
msgid "Enable IPV6 DNS Server" msgid "Enable IPV6 DNS Server"
msgstr "启用IPV6服务器" msgstr "启用IPV6服务器"
msgid "Dual-stack IP Selection"
msgstr "双栈IP优选"
msgid "Enable IP selection between IPV4 and IPV6"
msgstr "启用或禁用IPV4IPV6间的IP优选策略。"
msgid "Redirect" msgid "Redirect"
msgstr "重定向" msgstr "重定向"
@@ -127,6 +133,9 @@ msgstr "IP黑名单过滤"
msgid "Filtering IP with blacklist" msgid "Filtering IP with blacklist"
msgstr "使用IP黑名单过滤" msgstr "使用IP黑名单过滤"
msgid "Upstream DNS Server Configuration"
msgstr "上游DNS服务器配置"
msgid "Set Specific domain ip address." msgid "Set Specific domain ip address."
msgstr "指定特定域名的IP地址" msgstr "指定特定域名的IP地址"

View File

@@ -52,6 +52,14 @@ o.cfgvalue = function(...)
return Flag.cfgvalue(...) or "1" return Flag.cfgvalue(...) or "1"
end 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 ---- Redirect
o = s:taboption("settings", ListValue, "redirect", translate("Redirect"), translate("SmartDNS redirect mode")) o = s:taboption("settings", ListValue, "redirect", translate("Redirect"), translate("SmartDNS redirect mode"))
o.placeholder = "none" o.placeholder = "none"
@@ -102,6 +110,15 @@ s = m:section(TypedSection, "server", translate("Upstream Servers"), translate("
s.anonymous = true s.anonymous = true
s.addremove = true s.addremove = true
s.template = "cbi/tblsection" 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 ---- name
s:option(Value, "name", translate("Name"), translate("DNS Server name")) s:option(Value, "name", translate("Name"), translate("DNS Server name"))
@@ -124,14 +141,6 @@ o:value("tls", translate("tls"))
o.default = "udp" o.default = "udp"
o.rempty = false 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 -- Doman addresss
s = m:section(TypedSection, "smartdns", translate("Domain Address"), s = m:section(TypedSection, "smartdns", translate("Domain Address"),
translate("Set Specific domain ip address.")) translate("Set Specific domain ip address."))

View File

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

View File

@@ -113,11 +113,16 @@ load_server()
{ {
local section="$1" local section="$1"
local ADDITIONAL_ARGS="" local ADDITIONAL_ARGS=""
config_get_bool "enabled" "$section" "enabled" "1"
config_get "port" "$section" "port" "53" config_get "port" "$section" "port" "53"
config_get "type" "$section" "type" "udp" config_get "type" "$section" "type" "udp"
config_get "ip" "$section" "ip" "" config_get "ip" "$section" "ip" ""
config_get "blacklist_ip" "$section" "blacklist_ip" "0" config_get "blacklist_ip" "$section" "blacklist_ip" "0"
if [ "$enabled" = "0" ]; then
return
fi
if [ -z "$port" ] || [ -z "$ip" ] || [ -z "$type" ]; then if [ -z "$port" ] || [ -z "$ip" ] || [ -z "$type" ]; then
return return
fi fi
@@ -167,6 +172,11 @@ start_service() {
conf_append "bind-tcp" ":$port" conf_append "bind-tcp" ":$port"
fi fi
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" SMARTDNS_PORT="$port"
mkdir -p $SMARTDNS_CONF_DIR mkdir -p $SMARTDNS_CONF_DIR
@@ -215,15 +225,26 @@ start_service() {
config_get "old_redirect" "$section" "old_redirect" "none" config_get "old_redirect" "$section" "old_redirect" "none"
config_get "old_port" "$section" "old_port" "0" 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" clear_iptable "$old_port" "$ipv6_server"
stop_forward_dnsmasq "$old_port" if [ "$redirect" = "redirect" ]; then
set_iptable $ipv6_server $tcp_server
fi
fi fi
if [ "$redirect" = "redirect" ]; then if [ "$old_redirect" != "$redirect" ]; then
set_iptable $ipv6_server $tcp_server if [ "$old_redirect" != "none" ]; then
elif [ "$redirect" = "dnsmasq-upstream" ]; then if [ "$old_port" != "0" ]; then
set_forward_dnsmasq "$SMARTDNS_PORT" 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 fi
uci delete smartdns.@smartdns[0].old_redirect 2>/dev/null uci delete smartdns.@smartdns[0].old_redirect 2>/dev/null

View File

@@ -51,7 +51,7 @@ case "$1" in
fi fi
;; ;;
status) status)
pid="`cat $SMARTDNS_PID 2>/dev/null`" pid="`cat $SMARTDNS_PID |head -n 1 2>/dev/null`"
if [ -z "$pid" ]; then if [ -z "$pid" ]; then
echo "smartdns not running." echo "smartdns not running."
return 0 return 0
@@ -66,7 +66,16 @@ case "$1" in
;; ;;
stop) stop)
clear_iptable 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 kill -9 $pid 2>/dev/null
;; ;;
force-reload|restart) force-reload|restart)

View File

@@ -36,8 +36,8 @@ int dns_conf_audit_num = 2;
art_tree dns_conf_domain_rule; art_tree dns_conf_domain_rule;
radix_tree_t *dns_conf_address_rule; radix_tree_t *dns_conf_address_rule;
int dns_conf_dualstack_preference; int dns_conf_dualstack_ip_selection;
int dns_conf_dualstack_threshold = 1000; // cent usecond int dns_conf_dualstack_ip_selection_threshold = 100;
int dns_conf_rr_ttl; int dns_conf_rr_ttl;
int dns_conf_rr_ttl_min; 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("tcp-idle-time", &dns_conf_tcp_idle_time, 0, 3600),
CONF_INT("cache-size", &dns_conf_cachesize, 0, CONF_INT_MAX), CONF_INT("cache-size", &dns_conf_cachesize, 0, CONF_INT_MAX),
CONF_YESNO("prefetch-domain", &dns_conf_prefetch), CONF_YESNO("prefetch-domain", &dns_conf_prefetch),
CONF_YESNO("dualstack-preference", &dns_conf_dualstack_preference), CONF_YESNO("dualstack-ip-selection", &dns_conf_dualstack_ip_selection),
CONF_INT("dualstack-preference-threshold", &dns_conf_dualstack_threshold, 100, 10000), CONF_INT("dualstack-ip-selection-threshold", &dns_conf_dualstack_ip_selection_threshold, 1, 1000),
CONF_CUSTOM("log-level", config_log_level, NULL), CONF_CUSTOM("log-level", config_log_level, NULL),
CONF_STRING("log-file", (char *)dns_conf_log_file, DNS_MAX_PATH), CONF_STRING("log-file", (char *)dns_conf_log_file, DNS_MAX_PATH),
CONF_SIZE("log-size", &dns_conf_log_size, 0, 1024 * 1024 * 1024), CONF_SIZE("log-size", &dns_conf_log_size, 0, 1024 * 1024 * 1024),

View File

@@ -106,8 +106,8 @@ extern char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN];
extern art_tree dns_conf_domain_rule; extern art_tree dns_conf_domain_rule;
extern radix_tree_t *dns_conf_address_rule; extern radix_tree_t *dns_conf_address_rule;
extern int dns_conf_dualstack_preference; extern int dns_conf_dualstack_ip_selection;
extern int dns_conf_dualstack_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_min; extern int dns_conf_rr_ttl_min;

View File

@@ -521,7 +521,7 @@ int _dns_server_request_complete(struct dns_request *request)
if (request->has_ipv4) { 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); 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."); tlog(TLOG_DEBUG, "Force IPV4 perfered.");
return _dns_server_reply_SOA(DNS_RC_NOERROR, request, NULL); 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); memcpy(request->ipv4_addr, &addr_in->sin_addr.s_addr, 4);
} }
if (dns_conf_dualstack_preference == 1 && request->qtype == DNS_T_AAAA) { if (dns_conf_dualstack_ip_selection == 1 && request->qtype == DNS_T_AAAA) {
threshold = dns_conf_dualstack_threshold; threshold = dns_conf_dualstack_ip_selection_threshold * 10;
} }
} break; } break;
case AF_INET6: { case AF_INET6: {
@@ -861,7 +861,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
unsigned char addr[4]; unsigned char addr[4];
if (request->qtype != DNS_T_A) { if (request->qtype != DNS_T_A) {
/* ignore non-matched query type */ /* ignore non-matched query type */
if (dns_conf_dualstack_preference == 0) { if (dns_conf_dualstack_ip_selection == 0) {
break; 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 */ /* 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) {
_dns_server_request_complete(request); _dns_server_request_complete(request);
_dns_server_request_remove(request);
} }
if (request->has_ipv4 == 0 && request->has_ipv6 == 0) { 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++; request->request_wait++;
dns_client_query(request->domain, qtype, dns_server_resolve_callback, request); 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); _dns_server_request_get(request);
request->request_wait++; request->request_wait++;
dns_client_query(request->domain, DNS_T_A, dns_server_resolve_callback, request); 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 total_len = dnsserver->recvbuff.size;
int proceed_len = 0; int proceed_len = 0;
unsigned char *request_data = NULL; unsigned char *request_data = NULL;
int ret = 0;
for (;;) { for (;;) {
if ((total_len - proceed_len) <= sizeof(unsigned short)) { if ((total_len - proceed_len) <= sizeof(unsigned short)) {
return 1; ret = 1;
break;
} }
request_len = ntohs(*((unsigned short *)(dnsserver->recvbuff.buf + proceed_len))); 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)) { if (request_len > (total_len - proceed_len)) {
return 1; ret = 1;
break;
} }
request_data = (unsigned char *)(dnsserver->recvbuff.buf + proceed_len + sizeof(unsigned short)); 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; dnsserver->recvbuff.size -= proceed_len;
return 0; return ret;
} }
int _dns_server_tcp_process_requests(struct dns_server_conn *client) int _dns_server_tcp_process_requests(struct dns_server_conn *client)