Compare commits

..

7 Commits

Author SHA1 Message Date
Nick Peng
64e5b326cc luci: fix status section not working issue and add some options 2022-08-28 17:30:24 +08:00
Nick Peng
f659cf3725 dns_conf: support relative path for dnsmasq-lease-file 2022-08-28 10:22:14 +08:00
Nick Peng
83c8105312 dns_server: fix only cache on ip address result issue 2022-08-24 20:05:35 +08:00
Nick Peng
fecc313e03 dns_server: fix SERVERFAIL when A is 127.0.0.1 2022-08-23 22:49:41 +08:00
Nick Peng
145f7cfa42 dns_server: make the TTL of the first request to 2s & fix hostname issue. 2022-08-21 18:29:44 +08:00
Nick Peng
464f2adaa7 fast_ping: fix race condition 2022-08-21 18:29:44 +08:00
Zhong Lufan
7c9288f887 Readme: Fix typo 2022-08-19 19:36:46 +08:00
11 changed files with 124 additions and 23 deletions

View File

@@ -579,7 +579,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
| server-tls | 上游 TLS DNS | 无 | 可重复。<br>[ip][:port]:服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]TLS 合法性校验 SPKI 值base64 编码的 sha256 SPKI pin 值<br>[-host-name]TLS SNI 名称<br>[-tls-host-verify]TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围<br>[-group [group] ...]DNS 服务器所属组,比如 office 和 foreign和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-tls 8.8.8.8:853 |
| server-https | 上游 HTTPS DNS | 无 | 可重复。<br>https://[host][:port]/path服务器 IP:端口(可选)<br>[-spki-pin [sha256-pin]]TLS 合法性校验 SPKI 值base64 编码的 sha256 SPKI pin 值<br>[-host-name]TLS SNI 名称<br>[-http-host]http 协议头主机名<br>[-tls-host-verify]TLS 证书主机名校验<br> [-no-check-certificate]:跳过证书校验<br>[-blacklist-ip]:配置 IP 过滤结果<br>[-whitelist-ip]:仅接受参数中配置的 IP 范围。<br>[-group [group] ...]DNS 服务器所属组,比如 office 和 foreign和 nameserver 配套使用<br>[-exclude-default-group]:将 DNS 服务器从默认组中排除 | server-https https://cloudflare-dns.com/dns-query |
| speed-check-mode | 测速模式选择 | 无 | [ping\|tcp:[80]\|none] | speed-check-mode ping,tcp:80,tcp:443 |
| response-mode | 首次查询响应模式 | first-ping |模式:[fisrt-ping\|fastest-ip\|first-response]<br> [first-ping]: 最快ping响应地址模式DNS上游最快查询时延+ping时延最短查询等待与链接体验最佳;<br>[fastest-ip]: 最快IP地址模式查询到的所有IP地址中ping最短的IP。需等待IP测速; <br>[first-response]: 最快响应的DNS结果DNS查询等待时间最短返回的IP地址可能不是最快。| response-mode first-ping |
| response-mode | 首次查询响应模式 | first-ping |模式:[fisrt-ping\|fastest-ip\|fastest-response]<br> [first-ping]: 最快ping响应地址模式DNS上游最快查询时延+ping时延最短查询等待与链接体验最佳;<br>[fastest-ip]: 最快IP地址模式查询到的所有IP地址中ping最短的IP。需等待IP测速; <br>[fastest-response]: 最快响应的DNS结果DNS查询等待时间最短返回的IP地址可能不是最快。| response-mode first-ping |
| address | 指定域名 IP 地址 | 无 | address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6] <br>- 表示忽略 <br># 表示返回 SOA <br>4 表示 IPv4 <br>6 表示 IPv6 | address /www.example.com/1.2.3.4 |
| nameserver | 指定域名使用 server 组解析 | 无 | nameserver /domain/[group\|-], group 为组名,- 表示忽略此规则,配套 server 中的 -group 参数使用 | nameserver /www.example.com/office |
| ipset | 域名 ipset | 无 | ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]]-表示忽略 | ipset /www.example.com/#4:dns4,#6:- |

View File

@@ -515,7 +515,7 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|server-tls|Upstream TLS DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tls 8.8.8.8:853
|server-https|Upstream HTTPS DNS server|None|Repeatable <br>`https://[host][:port]/path`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name<br>`[-http-host]`http header host. <br>`[-tls-host-verify]`: TLS cert hostname to verify. <br>`-no-check-certificate:`: No check certificate. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-https https://cloudflare-dns.com/dns-query
|speed-check-mode|Speed mode|None|[ping\|tcp:[80]\|none]|speed-check-mode ping,tcp:80,tcp:443
|response-mode|First query response mode|first-ping|Mode: [fisrt-ping\|fastest-ip\|first-response]<br> [first-ping]: The fastest dns + ping response mode, DNS query delay + ping delay is the shortest;<br>[fastest-ip]: The fastest IP address mode, return the fastest ip address, may take some time to test speed. <br>[first-response]: The fastest response DNS result mode, the DNS query waiting time is the shortest. | response-mode first-ping |
|response-mode|First query response mode|first-ping|Mode: [fisrt-ping\|fastest-ip\|fastest-response]<br> [first-ping]: The fastest dns + ping response mode, DNS query delay + ping delay is the shortest;<br>[fastest-ip]: The fastest IP address mode, return the fastest ip address, may take some time to test speed. <br>[fastest-response]: The fastest response DNS result mode, the DNS query waiting time is the shortest. | response-mode first-ping |
|address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4
|nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office
|ipset|Domain IPSet|None|ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]], `-` for ignore|ipset /www.example.com/#4:dns4,#6:-

View File

@@ -36,7 +36,9 @@
# IPV6:
# bind [::]:53
# bind-tcp [::]:53
bind [::]:53
bind [::]:7053
force-AAAA-SOA yes
# tcp connection idle timeout
# tcp-idle-time [second]

View File

@@ -109,6 +109,12 @@ msgstr "重定向53端口到SmartDNS"
msgid "Cache Size"
msgstr "缓存大小"
msgid "Resolve Local Hostnames"
msgstr "本地主机名解析"
msgid "Resolve local hostnames by reading Dnsmasq lease file"
msgstr "读取Dnsmasq的DHCP Lease文件解析本地主机名"
msgid "DNS domain result cache size"
msgstr "缓存DNS的结果缓存大小配置零则不缓存单位"
@@ -193,8 +199,8 @@ msgstr "跳过cache。"
msgid "Force AAAA SOA"
msgstr "停用IPV6地址解析"
msgid "Force AAAA SOA."
msgstr "停用IPV6地址解析。"
msgid "Force HTTPS SOA."
msgstr "停用HTTPS解析。"
msgid "Upstream Servers"
msgstr "上游服务器"

View File

@@ -31,7 +31,7 @@ var callServiceList = rpc.declare({
expect: { '': {} }
});
function getPidOfSmartdns() {
function getServiceStatus() {
return L.resolveDefault(callServiceList(conf), {})
.then(function (res) {
var isrunning = false;
@@ -49,6 +49,8 @@ function getIPTablesRedirect() {
} else {
return "";
}
}).catch(function (err) {
return "";
});
}
@@ -59,12 +61,14 @@ function getIP6TablesRedirect() {
} else {
return "";
}
});
}).catch(function (err) {
return "";
});;
}
function smartdnsServiceStatus() {
return Promise.all([
getPidOfSmartdns(),
getServiceStatus(),
getIPTablesRedirect(),
getIP6TablesRedirect()
]);
@@ -136,6 +140,10 @@ return L.view.extend({
L.Poll.add(function () {
return L.resolveDefault(smartdnsServiceStatus()).then(function (res) {
var view = document.getElementById("service_status");
if (view == null) {
return;
}
view.innerHTML = smartdnsRenderStatus(res);
});
});
@@ -215,6 +223,21 @@ return L.view.extend({
o = s.taboption("settings", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size"));
o.rempty = true;
// cache-size;
o = s.taboption("settings", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file"));
o.rmempty = false;
o.default = o.enabled;
// Force AAAA SOA
o = s.taboption("settings", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA."));
o.rmempty = false;
o.default = o.disabled;
// Force HTTPS SOA
o = s.taboption("settings", form.Flag, "force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA."));
o.rmempty = false;
o.default = o.disabled;
// rr-ttl;
o = s.taboption("settings", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result."));
o.rempty = true;

View File

@@ -260,6 +260,8 @@ load_service()
{
local section="$1"
args=""
dnsmase_lease_file="$(uci get dhcp.@dnsmasq[0].leasefile 2>/dev/null)"
qtype_soa_list=""
mkdir -p $SMARTDNS_VAR_CONF_DIR
rm -f $SMARTDNS_CONF_TMP
@@ -302,6 +304,15 @@ load_service()
config_get cache_size "$section" "cache_size" ""
[ -z "$cache_size" ] || conf_append "cache-size" "$cache_size"
config_get resolve_local_hostnames "$section" "resolve_local_hostnames" "1"
[ -z "$resolve_local_hostnames" ] || conf_append "dnsmasq-lease-file" "$dnsmase_lease_file"
config_get force_aaaa_soa "$section" "force_aaaa_soa" "0"
[ "$force_aaaa_soa" = "1" ] && qtype_soa_list="$qtype_soa_list 28"
config_get force_https_soa "$section" "force_https_soa" "0"
[ "$force_https_soa" = "1" ] && qtype_soa_list="$qtype_soa_list 65"
config_get rr_ttl "$section" "rr_ttl" ""
[ -z "$rr_ttl" ] || conf_append "rr-ttl" "$rr_ttl"
@@ -331,6 +342,8 @@ load_service()
config_get old_port "$section" "old_port" "0"
config_get old_enabled "$section" "old_enabled" "0"
[ -z "$qtype_soa_list" ] || conf_append "force-qtype-SOA" "$qtype_soa_list"
if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$SMARTDNS_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then
[ "$old_redirect" = "none" ] || {
[ "$old_port" = "0" ] || clear_iptable "$old_port" "$ipv6_server"

View File

@@ -1750,8 +1750,8 @@ static int _conf_dhcp_lease_dnsmasq_file(void *data, int argc, char *argv[])
return -1;
}
safe_strncpy(dns_conf_dnsmasq_lease_file, argv[1], DNS_MAX_PATH);
if (_conf_dhcp_lease_dnsmasq_add(argv[1]) != 0) {
conf_get_conf_fullpath(argv[1], dns_conf_dnsmasq_lease_file, sizeof(dns_conf_dnsmasq_lease_file));
if (_conf_dhcp_lease_dnsmasq_add(dns_conf_dnsmasq_lease_file) != 0) {
return -1;
}
@@ -2093,6 +2093,15 @@ static int _dns_conf_load_post(void)
dns_conf_response_mode_enum[dns_conf_response_mode].name);
}
if ((dns_conf_rr_ttl_min > dns_conf_rr_ttl_max) && dns_conf_rr_ttl_max > 0) {
dns_conf_rr_ttl_min = dns_conf_rr_ttl_max;
}
if ((dns_conf_rr_ttl_max < dns_conf_rr_ttl_min) && dns_conf_rr_ttl_max > 0) {
dns_conf_rr_ttl_max = dns_conf_rr_ttl_min;
}
if (dns_conf_local_ttl == 0) {
dns_conf_local_ttl = dns_conf_rr_ttl_min;
}

View File

@@ -1566,6 +1566,7 @@ static int _dns_server_force_dualstack(struct dns_request *request)
static int _dns_server_request_complete(struct dns_request *request)
{
int ttl = DNS_SERVER_TMOUT_TTL;
int reply_ttl = ttl;
if (request->rcode == DNS_RC_SERVFAIL || request->rcode == DNS_RC_NXDOMAIN) {
ttl = DNS_SERVER_FAIL_TTL;
@@ -1617,6 +1618,15 @@ out:
}
}
reply_ttl = ttl;
if (request->passthrough == 0 && dns_conf_cachesize > 0 &&
request->check_order_list->orders[0].type != DOMAIN_CHECK_NONE) {
reply_ttl = dns_conf_serve_expired_reply_ttl;
if (reply_ttl < 2) {
reply_ttl = 2;
}
}
struct dns_server_post_context context;
_dns_server_post_context_init(&context, request);
context.do_cache = 1;
@@ -1624,7 +1634,7 @@ out:
context.do_force_soa = request->dualstack_selection_force_soa;
context.do_audit = 1;
context.do_reply = 1;
context.reply_ttl = ttl;
context.reply_ttl = reply_ttl;
context.skip_notify_count = 1;
_dns_request_post(&context);
@@ -1814,6 +1824,10 @@ static void _dns_server_complete_with_multi_ipaddress(struct dns_request *reques
_dns_server_force_dualstack(request);
}
if (request->passthrough && do_reply == 0) {
return;
}
_dns_server_post_context_init(&context, request);
context.do_cache = 1;
context.do_ipset = 1;
@@ -2312,6 +2326,7 @@ static int _dns_server_process_answer_A(struct dns_rrs *rrs, struct dns_request
if (addr[0] == 0 || addr[0] == 127) {
/* If half of the servers return the same result, then ignore this address */
if (atomic_inc_return(&request->adblock) <= (dns_server_num() / 2 + dns_server_num() % 2)) {
request->rcode = DNS_RC_NOERROR;
_dns_server_request_release(request);
return -1;
}
@@ -2388,6 +2403,7 @@ static int _dns_server_process_answer_AAAA(struct dns_rrs *rrs, struct dns_reque
if (_dns_server_is_adblock_ipv6(addr) == 0) {
/* If half of the servers return the same result, then ignore this address */
if (atomic_inc_return(&request->adblock) <= (dns_server_num() / 2 + dns_server_num() % 2)) {
request->rcode = DNS_RC_NOERROR;
_dns_server_request_release(request);
return -1;
}
@@ -3023,7 +3039,7 @@ static int _dns_server_reply_request_eth_ip(struct dns_request *request)
}
request->rcode = DNS_RC_NOERROR;
request->ip_ttl = 600;
request->ip_ttl = dns_conf_local_ttl;
request->has_ip = 1;
struct dns_server_post_context context;
@@ -3813,10 +3829,6 @@ static int _dns_server_process_special_query(struct dns_request *request)
{
int ret = 0;
if (_dns_server_process_smartdns_domain(request) == 0) {
goto clean_exit;
}
switch (request->qtype) {
case DNS_T_PTR:
/* return PTR record */
@@ -4057,6 +4069,10 @@ static int _dns_server_do_query(struct dns_request *request)
goto clean_exit;
}
if (_dns_server_process_smartdns_domain(request) == 0) {
goto clean_exit;
}
if (_dns_server_process_host(request) == 0) {
goto clean_exit;
}

View File

@@ -1112,10 +1112,6 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
tlog(TLOG_DEBUG, "ping %s, id = %d", host, ping_host->sid);
addrkey = _fast_ping_hash_key(ping_host->sid, &ping_host->addr);
pthread_mutex_lock(&ping.map_lock);
_fast_ping_host_get(ping_host);
hash_add(ping.addrmap, &ping_host->addr_node, addrkey);
pthread_mutex_unlock(&ping.map_lock);
_fast_ping_host_get(ping_host);
_fast_ping_host_get(ping_host);
@@ -1124,7 +1120,11 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
goto errout_remove;
}
pthread_mutex_lock(&ping.map_lock);
_fast_ping_host_get(ping_host);
hash_add(ping.addrmap, &ping_host->addr_node, addrkey);
ping_host->run = 1;
pthread_mutex_unlock(&ping.map_lock);
freeaddrinfo(gai);
_fast_ping_host_put(ping_host);
return ping_host;

View File

@@ -160,4 +160,6 @@ void load_exit(void);
const char *conf_get_conf_file(void);
const char *conf_get_conf_fullpath(const char *path, char *fullpath, size_t path_len);
#endif // !_GENERIC_CONF_H

View File

@@ -18,16 +18,46 @@
#include "conf.h"
#include <getopt.h>
#include <libgen.h>
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static const char *currrent_conf_file = NULL;
static const char *current_conf_file = NULL;
const char *conf_get_conf_file(void)
{
return currrent_conf_file;
return current_conf_file;
}
const char *conf_get_conf_fullpath(const char *path, char *fullpath, size_t path_len)
{
char file_path_dir[PATH_MAX];
if (path_len < 1) {
return NULL;
}
if (path[0] == '/') {
strncpy(fullpath, path, path_len);
return fullpath;
}
strncpy(file_path_dir, conf_get_conf_file(), PATH_MAX - 1);
file_path_dir[PATH_MAX - 1] = 0;
dirname(file_path_dir);
if (file_path_dir[0] == '\0') {
strncpy(fullpath, path, path_len);
return fullpath;
}
if (snprintf(fullpath, PATH_MAX, "%s/%s", file_path_dir, path) < 0) {
return NULL;
}
return fullpath;
}
int conf_custom(const char *item, void *data, int argc, char *argv[])
@@ -303,7 +333,7 @@ static int load_conf_file(const char *file, struct config_item *items, conf_erro
conf_getopt_reset();
/* call item function */
currrent_conf_file = file;
current_conf_file = file;
call_ret = items[i].item_func(items[i].item, items[i].data, argc, argv);
ret = handler(file, line_no, call_ret);
if (ret != 0) {