Compare commits
1 Commits
quic
...
https-svcb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27c1aedd3b |
@@ -18,9 +18,7 @@ Checks: >
|
||||
-bugprone-suspicious-memory-comparison,
|
||||
-bugprone-not-null-terminated-result,
|
||||
-bugprone-signal-handler,
|
||||
-bugprone-assignment-in-if-condition,
|
||||
-concurrency-mt-unsafe,
|
||||
-modernize-macro-to-enum,
|
||||
-misc-unused-parameters,
|
||||
-misc-misplaced-widening-cast,
|
||||
-misc-no-recursion,
|
||||
|
||||
@@ -37,7 +37,7 @@ test -x $SMARTDNS || exit 5
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
$SMARTDNS "$SMART_DNS_OPTS" -R
|
||||
$SMARTDNS "$SMART_DNS_OPTS"
|
||||
while true; do
|
||||
if [ -e "$PIDFILE" ]; then
|
||||
break;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
# Include another configuration options
|
||||
# conf-file [file]
|
||||
# conf-file blacklist-ip.conf
|
||||
# conf-file *.conf
|
||||
|
||||
# dns server bind ip and port, default dns server port is 53, support binding multi ip and port
|
||||
# bind udp server
|
||||
@@ -31,8 +30,6 @@
|
||||
# tls cert file
|
||||
# bind-cert-key-pass [password]
|
||||
# tls private key password
|
||||
# bind-https server
|
||||
# bind-https [IP]:[port][@device] [-group [group]] [-no-rule-addr] [-no-rule-nameserver] [-no-rule-ipset] [-no-speed-check] [-no-cache] [-no-rule-soa] [-no-dualstack-selection]
|
||||
# option:
|
||||
# -group: set domain request to use the appropriate server group.
|
||||
# -no-rule-addr: skip address rule.
|
||||
@@ -205,7 +202,6 @@ log-level info
|
||||
# -host-ip [ip]: set dns server host ip.
|
||||
# server 8.8.8.8 -blacklist-ip -check-edns -group g1 -group g2
|
||||
# server tls://dns.google:853
|
||||
# server quic://dns.gooel.com:443
|
||||
# server https://dns.google/dns-query
|
||||
|
||||
# remote tcp dns server list
|
||||
@@ -227,20 +223,6 @@ log-level info
|
||||
# server-tls 8.8.8.8
|
||||
# server-tls 1.0.0.1
|
||||
|
||||
# remote quic dns server list
|
||||
# server-quic [IP]:[PORT] [-blacklist-ip] [-whitelist-ip] [-spki-pin [sha256-pin]] [-group [group] ...] [-exclude-default-group]
|
||||
# -spki-pin: TLS spki pin to verify.
|
||||
# -tls-host-verify: cert hostname to verify.
|
||||
# -host-name: TLS sni hostname.
|
||||
# k|-no-check-certificate: no check certificate.
|
||||
# p|-proxy [proxy-name]: use proxy to connect to server.
|
||||
# -bootstrap-dns: set as bootstrap dns server.
|
||||
# Get SPKI with this command:
|
||||
# echo | openssl s_client -connect '[ip]:443' | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
|
||||
# default port is 443
|
||||
# server-quic 8.8.8.8
|
||||
# server-quic 1.0.0.1
|
||||
|
||||
# remote https dns server list
|
||||
# server-https https://[host]:[port]/path [-blacklist-ip] [-whitelist-ip] [-spki-pin [sha256-pin]] [-group [group] ...] [-exclude-default-group]
|
||||
# -spki-pin: TLS spki pin to verify.
|
||||
@@ -280,11 +262,6 @@ log-level info
|
||||
# specific cname to domain
|
||||
# cname /domain/target
|
||||
|
||||
# add srv record, support multiple srv record.
|
||||
# srv-record /domain/[target][,port][,priority][,weight]
|
||||
# srv-record /_ldap._tcp.example.com/ldapserver.example.com,389
|
||||
# srv-record /_ldap._tcp.example.com/
|
||||
|
||||
# enalbe DNS64 feature
|
||||
# dns64 [ip/subnet]
|
||||
# dns64 64:ff9b::/96
|
||||
@@ -371,4 +348,3 @@ log-level info
|
||||
# ip-set -name ip-list -file /etc/smartdns/ip-list.conf
|
||||
# bogus-nxdomain ip-set:ip-list
|
||||
# ip-alias ip-set:ip-list 1.2.3.4
|
||||
# ip-alias ip-set:ip-list ip-set:ip-map-list
|
||||
|
||||
@@ -67,18 +67,6 @@ msgstr "配置分流域名列表"
|
||||
msgid "Custom Settings"
|
||||
msgstr "自定义设置"
|
||||
|
||||
msgid "DOH Server"
|
||||
msgstr "DOH服务器"
|
||||
|
||||
msgid "DOH Server Port"
|
||||
msgstr "DOH服务器端口"
|
||||
|
||||
msgid "DOT Server"
|
||||
msgstr "DOT服务器"
|
||||
|
||||
msgid "DOT Server Port"
|
||||
msgstr "DOT服务器端口"
|
||||
|
||||
msgid "DNS Block Setting"
|
||||
msgstr "域名屏蔽设置"
|
||||
|
||||
@@ -196,44 +184,8 @@ msgstr "启用IPV6服务器。"
|
||||
msgid "Enable TCP DNS Server"
|
||||
msgstr "启用TCP服务器。"
|
||||
|
||||
msgid "Enable daily(week) auto update."
|
||||
msgstr "启用每天(每周)自动更新。"
|
||||
|
||||
msgid "Enable DOH DNS Server"
|
||||
msgstr "启用DOH服务器。"
|
||||
|
||||
msgid "Enable DOT DNS Server"
|
||||
msgstr "启用DOT服务器。"
|
||||
|
||||
msgid "Update Time (Every Week)"
|
||||
msgstr "更新时间(每周)"
|
||||
|
||||
msgid "Every Day"
|
||||
msgstr "每天"
|
||||
|
||||
msgid "Every Monday"
|
||||
msgstr "每周一"
|
||||
|
||||
msgid "Every Tuesday"
|
||||
msgstr "每周二"
|
||||
|
||||
msgid "Every Wednesday"
|
||||
msgstr "每周三"
|
||||
|
||||
msgid "Every Thursday"
|
||||
msgstr "每周四"
|
||||
|
||||
msgid "Every Friday"
|
||||
msgstr "每周五"
|
||||
|
||||
msgid "Every Saturday"
|
||||
msgstr "每周六"
|
||||
|
||||
msgid "Every Sunday"
|
||||
msgstr "每周日"
|
||||
|
||||
msgid "Update Time (Every Day)"
|
||||
msgstr "更新时间(每天)"
|
||||
msgid "Enable daily auto update."
|
||||
msgstr "启用每日自动更新"
|
||||
|
||||
msgid "Enable domain prefetch, accelerate domain response speed."
|
||||
msgstr "启用域名预加载,加速域名响应速度。"
|
||||
@@ -446,15 +398,6 @@ msgstr "重启服务"
|
||||
msgid "Second Server Settings"
|
||||
msgstr "第二DNS服务器"
|
||||
|
||||
msgid "Server certificate file path."
|
||||
msgstr "服务器证书文件路径。"
|
||||
|
||||
msgid "Server certificate key file path."
|
||||
msgstr "服务器证书私钥文件路径。"
|
||||
|
||||
msgid "Server certificate key file password."
|
||||
msgstr "服务器证书私钥文件密码。"
|
||||
|
||||
msgid "Serve expired"
|
||||
msgstr "缓存过期服务"
|
||||
|
||||
@@ -467,15 +410,6 @@ msgstr "服务器组%s不存在"
|
||||
msgid "Server Name"
|
||||
msgstr "服务器名称"
|
||||
|
||||
msgid "Server Cert"
|
||||
msgstr "服务器证书"
|
||||
|
||||
msgid "Server Cert Key"
|
||||
msgstr "服务器证书私钥"
|
||||
|
||||
msgid "Server Cert Key Pass"
|
||||
msgstr "服务器证书私钥密码"
|
||||
|
||||
msgid "Set Specific domain ip address."
|
||||
msgstr "设置指定域名的IP地址。"
|
||||
|
||||
@@ -544,12 +478,6 @@ msgstr "跳过Nameserver规则。"
|
||||
msgid "SmartDNS"
|
||||
msgstr "SmartDNS"
|
||||
|
||||
msgid "Smartdns DOH server port."
|
||||
msgstr "Smartdns DOH服务器端口号。
|
||||
|
||||
msgid "Smartdns DOT server port."
|
||||
msgstr "Smartdns DOT服务器端口号。"
|
||||
|
||||
msgid "SmartDNS Server"
|
||||
msgstr "SmartDNS 服务器"
|
||||
|
||||
@@ -720,4 +648,4 @@ msgid "type"
|
||||
msgstr "类型"
|
||||
|
||||
msgid "udp"
|
||||
msgstr "udp"
|
||||
msgstr "udp"
|
||||
|
||||
@@ -130,56 +130,6 @@ o.cfgvalue = function(...)
|
||||
return Flag.cfgvalue(...) or "1"
|
||||
end
|
||||
|
||||
---- Enable DOT server;
|
||||
o = s:taboption("advanced", Flag, "tls_server", translate("DOT Server"), translate("Enable DOT DNS Server"))
|
||||
o.rmempty = false
|
||||
o.default = o.disabled
|
||||
o.cfgvalue = function(...)
|
||||
return Flag.cfgvalue(...) or "0"
|
||||
end
|
||||
|
||||
o = s:taboption("advanced", Value, "tls_server_port", translate("DOT Server Port"), translate("Smartdns DOT server port."))
|
||||
o.placeholder = 853
|
||||
o.default = 853
|
||||
o.datatype = "port"
|
||||
o.rempty = false
|
||||
o:depends('tls_server', '1')
|
||||
|
||||
---- Enable DOH server;
|
||||
o = s:taboption("advanced", Flag, "doh_server", translate("DOH Server"), translate("Enable DOH DNS Server"))
|
||||
o.rmempty = false
|
||||
o.default = o.disabled
|
||||
o.cfgvalue = function(...)
|
||||
return Flag.cfgvalue(...) or "0"
|
||||
end
|
||||
|
||||
o = s:taboption("advanced", Value, "doh_server_port", translate("DOH Server Port"), translate("Smartdns DOH server port."))
|
||||
o.placeholder = 843
|
||||
o.default = 843
|
||||
o.datatype = "port"
|
||||
o.rempty = false
|
||||
o:depends('doh_server', '1')
|
||||
|
||||
o = s:taboption("advanced", Value, "bind_cert", translate("Server Cert"), translate("Server certificate file path."))
|
||||
o.datatype = "string"
|
||||
o.placeholder = "/var/etc/smartdns/smartdns/smartdns-cert.pem"
|
||||
o.rempty = true
|
||||
o:depends('tls_server', '1')
|
||||
o:depends('doh_server', '1')
|
||||
|
||||
o = s:taboption("advanced", Value, "bind_cert_key", translate("Server Cert Key"), translate("Server certificate key file path."))
|
||||
o.datatype = "string"
|
||||
o.placeholder = "/var/etc/smartdns/smartdns/smartdns-key.pem"
|
||||
o.rempty = false
|
||||
o:depends('tls_server', '1')
|
||||
o:depends('doh_server', '1')
|
||||
|
||||
o = s:taboption("advanced", Value, "bind_cert_key_pass", translate("Server Cert Key Pass"), translate("Server certificate key file password."))
|
||||
o.datatype = "string"
|
||||
o.rempty = false
|
||||
o:depends('tls_server', '1')
|
||||
o:depends('doh_server', '1')
|
||||
|
||||
---- Support IPV6
|
||||
o = s:taboption("advanced", Flag, "ipv6_server", translate("IPV6 Server"), translate("Enable IPV6 DNS Server"))
|
||||
o.rmempty = false
|
||||
@@ -721,26 +671,11 @@ s = m:section(TypedSection, "smartdns", translate("Download Files Setting"), tra
|
||||
s.anonymous = true
|
||||
|
||||
---- download Files Settings
|
||||
o = s:option(Flag, "enable_auto_update", translate("Enable Auto Update"), translate("Enable daily(week) auto update."))
|
||||
o = s:option(Flag, "enable_auto_update", translate("Enable Auto Update"), translate("Enable daily auto update."))
|
||||
o.rmempty = true
|
||||
o.default = o.disabled
|
||||
o.rempty = true
|
||||
|
||||
o = s:option(ListValue, "auto_update_week_time", translate("Update Time (Every Week)"))
|
||||
o:value("*", translate("Every Day"))
|
||||
o:value("1", translate("Every Monday"))
|
||||
o:value("2", translate("Every Tuesday"))
|
||||
o:value("3", translate("Every Wednesday"))
|
||||
o:value("4", translate("Every Thursday"))
|
||||
o:value("5", translate("Every Friday"))
|
||||
o:value("6", translate("Every Saturday"))
|
||||
o:value("0", translate("Every Sunday"))
|
||||
o.default = "*"
|
||||
|
||||
o = s:option(ListValue, "auto_update_day_time", translate("Update Time (Every Day)"))
|
||||
for i = 0, 23 do o:value(i, i .. ":00") end
|
||||
o.default = 5
|
||||
|
||||
o = s:option(FileUpload, "upload_conf_file", translate("Upload Config File"),
|
||||
translate("Upload smartdns config file to /etc/smartdns/conf.d"))
|
||||
o.rmempty = true
|
||||
@@ -845,3 +780,4 @@ o.write = function()
|
||||
end
|
||||
|
||||
return m
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ msgid ""
|
||||
"Additional Flags for rules, read help on domain-rule for more information."
|
||||
msgstr "额外的规则标识,具体参考domain-rule的帮助说明。"
|
||||
|
||||
msgid ""
|
||||
"Additional Flags for rules, read help on ip-rule for more information."
|
||||
msgstr "额外的规则标识,具体参考ip-rule的帮助说明。"
|
||||
|
||||
msgid "Additional Rule Flag"
|
||||
msgstr "额外规则标识"
|
||||
|
||||
@@ -33,21 +29,12 @@ msgstr "自动设置Dnsmasq"
|
||||
msgid "Automatically set as upstream of dnsmasq when port changes."
|
||||
msgstr "端口更改时自动设为 dnsmasq 的上游。"
|
||||
|
||||
msgid "Blacklist IP"
|
||||
msgstr "黑名单"
|
||||
|
||||
msgid "Blacklist IP Rule, Decline IP addresses within the range."
|
||||
msgstr "黑名单规则,拒绝指定范围的IP地址。"
|
||||
|
||||
msgid "Bind Device"
|
||||
msgstr "绑定到设备"
|
||||
|
||||
msgid "Bind Device Name"
|
||||
msgstr "绑定的设备名称"
|
||||
|
||||
msgid "Bogus nxdomain"
|
||||
msgstr "假冒IP"
|
||||
|
||||
msgid "Block domain"
|
||||
msgstr "屏蔽域名"
|
||||
|
||||
@@ -77,27 +64,9 @@ msgstr "配置域名规则列表"
|
||||
msgid "Configure forwarding domain name list."
|
||||
msgstr "配置分流域名列表"
|
||||
|
||||
msgid "Configure ip rule list."
|
||||
msgstr "配置IP规则列表"
|
||||
|
||||
msgid "Custom Settings"
|
||||
msgstr "自定义设置"
|
||||
|
||||
msgid "Do not use these IP addresses."
|
||||
msgstr "忽略这些IP地址"
|
||||
|
||||
msgid "DOH Server"
|
||||
msgstr "DOH服务器"
|
||||
|
||||
msgid "DOH Server Port"
|
||||
msgstr "DOH服务器端口"
|
||||
|
||||
msgid "DOT Server"
|
||||
msgstr "DOT服务器"
|
||||
|
||||
msgid "DOT Server Port"
|
||||
msgstr "DOT服务器端口"
|
||||
|
||||
msgid "DNS Block Setting"
|
||||
msgstr "域名屏蔽设置"
|
||||
|
||||
@@ -215,44 +184,8 @@ msgstr "启用IPV6服务器。"
|
||||
msgid "Enable TCP DNS Server"
|
||||
msgstr "启用TCP服务器。"
|
||||
|
||||
msgid "Enable daily (weekly) auto update."
|
||||
msgstr "启用每日(每周)自动更新"
|
||||
|
||||
msgid "Enable DOH DNS Server"
|
||||
msgstr "启用DOH服务器"
|
||||
|
||||
msgid "Enable DOT DNS Server"
|
||||
msgstr "启用DOT服务器"
|
||||
|
||||
msgid "Update time (every day)"
|
||||
msgstr "更新时间(每天)"
|
||||
|
||||
msgid "Update Time (Every Week)"
|
||||
msgstr "更新时间(每周)"
|
||||
|
||||
msgid "Every Day"
|
||||
msgstr "每天"
|
||||
|
||||
msgid "Every Monday"
|
||||
msgstr "每周一"
|
||||
|
||||
msgid "Every Tuesday"
|
||||
msgstr "每周二"
|
||||
|
||||
msgid "Every Wednesday"
|
||||
msgstr "每周三"
|
||||
|
||||
msgid "Every Thursday"
|
||||
msgstr "每周四"
|
||||
|
||||
msgid "Every Friday"
|
||||
msgstr "每周五"
|
||||
|
||||
msgid "Every Saturday"
|
||||
msgstr "每周六"
|
||||
|
||||
msgid "Every Sunday"
|
||||
msgstr "每周日"
|
||||
msgid "Enable daily auto update."
|
||||
msgstr "启用每日自动更新"
|
||||
|
||||
msgid "Enable domain prefetch, accelerate domain response speed."
|
||||
msgstr "启用域名预加载,加速域名响应速度。"
|
||||
@@ -326,30 +259,6 @@ msgstr "IP黑名单过滤"
|
||||
msgid "IPV6 Server"
|
||||
msgstr "IPV6服务器"
|
||||
|
||||
msgid "IP alias"
|
||||
msgstr "IP别名"
|
||||
|
||||
msgid "IP Addresses"
|
||||
msgstr "IP地址"
|
||||
|
||||
msgid "IP Address Mapping, Can be used for CDN acceleration with Anycast IP, such as Cloudflare's CDN."
|
||||
msgstr "IP地址映射,可用于支持AnyCast IP的CDN加速,比如Cloudflare的CDN。"
|
||||
|
||||
msgid "Ignore IP"
|
||||
msgstr "忽略IP"
|
||||
|
||||
msgid "IP Rule List"
|
||||
msgstr "IP规则列表"
|
||||
|
||||
msgid "IP Rule Name"
|
||||
msgstr "IP规则名称"
|
||||
|
||||
msgid "IP Set File"
|
||||
msgstr "IP集合列表文件"
|
||||
|
||||
msgid "IP addresses, CIDR format."
|
||||
msgstr "IP地址,CIDR格式。"
|
||||
|
||||
msgid "IPset Name"
|
||||
msgstr "IPset名称"
|
||||
|
||||
@@ -440,9 +349,6 @@ msgstr "无"
|
||||
msgid "Only socks5 proxy support udp server."
|
||||
msgstr "仅SOCKS5代理支持UDP服务器。"
|
||||
|
||||
msgid "Please check the system logs and check if the configuration is valid."
|
||||
msgstr "请检查系统日志,并检查配置是否合法。"
|
||||
|
||||
msgid "Please set proxy server first."
|
||||
msgstr "请先设置代理服务器。"
|
||||
|
||||
@@ -474,9 +380,6 @@ msgstr "设置返回给客户端的域名TTL最大值。"
|
||||
msgid "Report bugs"
|
||||
msgstr "报告BUG"
|
||||
|
||||
msgid "Return SOA when the requested result contains a specified IP address."
|
||||
msgstr "当结果包含对应范围的IP时,返回SOA。"
|
||||
|
||||
msgid "Resolve Local Hostnames"
|
||||
msgstr "解析本地主机名"
|
||||
|
||||
@@ -495,15 +398,6 @@ msgstr "重启服务"
|
||||
msgid "Second Server Settings"
|
||||
msgstr "第二DNS服务器"
|
||||
|
||||
msgid "Server certificate file path."
|
||||
msgstr "服务器证书文件路径。"
|
||||
|
||||
msgid "Server certificate key file path."
|
||||
msgstr "服务器证书私钥文件路径。"
|
||||
|
||||
msgid "Server certificate key file password."
|
||||
msgstr "服务器证书私钥文件密码。"
|
||||
|
||||
msgid "Serve expired"
|
||||
msgstr "缓存过期服务"
|
||||
|
||||
@@ -516,15 +410,6 @@ msgstr "服务器组%s不存在"
|
||||
msgid "Server Name"
|
||||
msgstr "服务器名称"
|
||||
|
||||
msgid "Server Cert"
|
||||
msgstr "服务器证书"
|
||||
|
||||
msgid "Server Cert Key"
|
||||
msgstr "服务器证书私钥"
|
||||
|
||||
msgid "Server Cert Key Pass"
|
||||
msgstr "服务器证书私钥密码"
|
||||
|
||||
msgid "Set Specific domain ip address."
|
||||
msgstr "设置指定域名的IP地址。"
|
||||
|
||||
@@ -534,9 +419,6 @@ msgstr "设置指定域名的规则列表。"
|
||||
msgid "Set Specific ip blacklist."
|
||||
msgstr "设置指定的 IP 黑名单列表。"
|
||||
|
||||
msgid "Set Specific ip rule list."
|
||||
msgstr "设置对应IP的规则。"
|
||||
|
||||
msgid "Set TLS hostname to verify."
|
||||
msgstr "设置校验TLS主机名。"
|
||||
|
||||
@@ -596,12 +478,6 @@ msgstr "跳过Nameserver规则。"
|
||||
msgid "SmartDNS"
|
||||
msgstr "SmartDNS"
|
||||
|
||||
msgid "Smartdns DOH server port."
|
||||
msgstr "Smartdns DOH服务器端口号。
|
||||
|
||||
msgid "Smartdns DOT server port."
|
||||
msgstr "Smartdns DOT服务器端口号。"
|
||||
|
||||
msgid "SmartDNS Server"
|
||||
msgstr "SmartDNS 服务器"
|
||||
|
||||
@@ -699,9 +575,6 @@ msgstr "上传域名列表文件,或在下载文件设置页面设置自动下
|
||||
msgid "Upload domain list file."
|
||||
msgstr "上传域名列表文件"
|
||||
|
||||
msgid "Upload IP set file."
|
||||
msgstr "上传IP集合列表文件。"
|
||||
|
||||
msgid "Upload smartdns config file to /etc/smartdns/conf.d"
|
||||
msgstr "上传配置文件到/etc/smartdns/conf.d"
|
||||
|
||||
@@ -729,12 +602,6 @@ msgstr ""
|
||||
"用于校验 TLS 服务器的有效性,数值为 Base64 编码的 SPKI 指纹,留空表示不验证 "
|
||||
"TLS 的合法性。"
|
||||
|
||||
msgid "Whitelist IP"
|
||||
msgstr "白名单"
|
||||
|
||||
msgid "Whitelist IP Rule, Accept IP addresses within the range."
|
||||
msgstr "白名单规则,接受指定范围的IP地址。"
|
||||
|
||||
msgid "Write cache to disk on exit and load on startup."
|
||||
msgstr "退出时保存cache到磁盘,启动时加载。"
|
||||
|
||||
|
||||
@@ -58,17 +58,12 @@ function smartdnsRenderStatus(res) {
|
||||
|
||||
var autoSetDnsmasq = uci.get_first('smartdns', 'smartdns', 'auto_set_dnsmasq');
|
||||
var smartdnsPort = uci.get_first('smartdns', 'smartdns', 'port');
|
||||
var smartdnsEnable = uci.get_first('smartdns', 'smartdns', 'enabled');
|
||||
var dnsmasqServer = uci.get_first('dhcp', 'dnsmasq', 'server');
|
||||
|
||||
if (isRunning) {
|
||||
renderHTML += "<span style=\"color:green;font-weight:bold\">SmartDNS - " + _("RUNNING") + "</span>";
|
||||
} else {
|
||||
renderHTML += "<span style=\"color:red;font-weight:bold\">SmartDNS - " + _("NOT RUNNING") + "</span>";
|
||||
if (smartdnsEnable === '1') {
|
||||
renderHTML += "<br /><span style=\"color:red;font-weight:bold\">" + _("Please check the system logs and check if the configuration is valid.");
|
||||
renderHTML += "</span>";
|
||||
}
|
||||
return renderHTML;
|
||||
}
|
||||
|
||||
@@ -84,6 +79,7 @@ function smartdnsRenderStatus(res) {
|
||||
|
||||
return renderHTML;
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
@@ -160,7 +156,7 @@ return view.extend({
|
||||
o.default = 53;
|
||||
o.datatype = "port";
|
||||
o.rempty = false;
|
||||
|
||||
|
||||
// auto-conf-dnsmasq;
|
||||
o = s.taboption("settings", form.Flag, "auto_set_dnsmasq", _("Automatically Set Dnsmasq"), _("Automatically set as upstream of dnsmasq when port changes."));
|
||||
o.rmempty = false;
|
||||
@@ -224,50 +220,6 @@ return view.extend({
|
||||
o.rmempty = false;
|
||||
o.default = o.enabled;
|
||||
|
||||
// Enable DOT server;
|
||||
o = s.taboption("advanced", form.Flag, "tls_server", _("DOT Server"), _("Enable DOT DNS Server"));
|
||||
o.rmempty = false;
|
||||
o.default = o.disabled;
|
||||
|
||||
o = s.taboption("advanced", form.Value, "tls_server_port", _("DOT Server Port"), _("Smartdns DOT server port."));
|
||||
o.placeholder = 853;
|
||||
o.default = 853;
|
||||
o.datatype = "port";
|
||||
o.rempty = false;
|
||||
o.depends('tls_server', '1');
|
||||
|
||||
// Enable DOH server;
|
||||
o = s.taboption("advanced", form.Flag, "doh_server", _("DOH Server"), _("Enable DOH DNS Server"));
|
||||
o.rmempty = false;
|
||||
o.default = o.disabled;
|
||||
|
||||
o = s.taboption("advanced", form.Value, "doh_server_port", _("DOH Server Port"), _("Smartdns DOH server port."));
|
||||
o.placeholder = 843;
|
||||
o.default = 843;
|
||||
o.datatype = "port";
|
||||
o.rempty = false;
|
||||
o.depends('doh_server', '1');
|
||||
|
||||
o = s.taboption("advanced", form.Value, "bind_cert", _("Server Cert"), _("Server certificate file path."));
|
||||
o.datatype = "string";
|
||||
o.placeholder = "/var/etc/smartdns/smartdns/smartdns-cert.pem"
|
||||
o.rempty = true;
|
||||
o.depends('tls_server', '1');
|
||||
o.depends('doh_server', '1');
|
||||
|
||||
o = s.taboption("advanced", form.Value, "bind_cert_key", _("Server Cert Key"), _("Server certificate key file path."));
|
||||
o.datatype = "string";
|
||||
o.placeholder = "/var/etc/smartdns/smartdns/smartdns-key.pem"
|
||||
o.rempty = false;
|
||||
o.depends('tls_server', '1');
|
||||
o.depends('doh_server', '1');
|
||||
|
||||
o = s.taboption("advanced", form.Value, "bind_cert_key_pass", _("Server Cert Key Pass"), _("Server certificate key file password."));
|
||||
o.datatype = "string";
|
||||
o.rempty = false;
|
||||
o.depends('tls_server', '1');
|
||||
o.depends('doh_server', '1');
|
||||
|
||||
// Support IPV6;
|
||||
o = s.taboption("advanced", form.Flag, "ipv6_server", _("IPV6 Server"), _("Enable IPV6 DNS Server"));
|
||||
o.rmempty = false;
|
||||
@@ -327,7 +279,7 @@ return view.extend({
|
||||
o.default = o.enabled;
|
||||
|
||||
// Ipset no speed.
|
||||
o = s.taboption("advanced", form.Value, "ipset_no_speed", _("No Speed IPset Name"),
|
||||
o = s.taboption("advanced", form.Value, "ipset_no_speed", _("No Speed IPset Name"),
|
||||
_("Ipset name, Add domain result to ipset when speed check fails."));
|
||||
o.rmempty = true;
|
||||
o.datatype = "string";
|
||||
@@ -348,7 +300,7 @@ return view.extend({
|
||||
}
|
||||
|
||||
// NFTset no speed.
|
||||
o = s.taboption("advanced", form.Value, "nftset_no_speed", _("No Speed NFTset Name"),
|
||||
o = s.taboption("advanced", form.Value, "nftset_no_speed", _("No Speed NFTset Name"),
|
||||
_("Nftset name, Add domain result to nftset when speed check fails, format: [#[4|6]:[family#table#set]]"));
|
||||
o.rmempty = true;
|
||||
o.datatype = "string";
|
||||
@@ -391,7 +343,7 @@ return view.extend({
|
||||
o.rempty = true;
|
||||
|
||||
// other args
|
||||
o = s.taboption("advanced", form.Value, "server_flags", _("Additional Server Args"),
|
||||
o = s.taboption("advanced", form.Value, "server_flags", _("Additional Server Args"),
|
||||
_("Additional server args, refer to the help description of the bind option."))
|
||||
o.default = ""
|
||||
o.rempty = true
|
||||
@@ -524,7 +476,7 @@ return view.extend({
|
||||
}
|
||||
|
||||
// other args
|
||||
o = s.taboption("seconddns", form.Value, "seconddns_server_flags", _("Additional Server Args"),
|
||||
o = s.taboption("seconddns", form.Value, "seconddns_server_flags", _("Additional Server Args"),
|
||||
_("Additional server args, refer to the help description of the bind option."))
|
||||
o.default = ""
|
||||
o.rempty = true
|
||||
@@ -540,29 +492,11 @@ return view.extend({
|
||||
///////////////////////////////////////
|
||||
// download Files Settings
|
||||
///////////////////////////////////////
|
||||
o = s.taboption("files", form.Flag, "enable_auto_update", _("Enable Auto Update"), _("Enable daily (weekly) auto update."));
|
||||
o = s.taboption("files", form.Flag, "enable_auto_update", _("Enable Auto Update"), _("Enable daily auto update."));
|
||||
o.rmempty = true;
|
||||
o.default = o.disabled;
|
||||
o.rempty = true;
|
||||
|
||||
o = s.taboption("files", form.ListValue, "auto_update_week_time", _("Update Time (Every Week)"));
|
||||
o.value('*', _('Every Day'));
|
||||
o.value('1', _('Every Monday'));
|
||||
o.value('2', _('Every Tuesday'));
|
||||
o.value('3', _('Every Wednesday'));
|
||||
o.value('4', _('Every Thursday'));
|
||||
o.value('5', _('Every Friday'));
|
||||
o.value('6', _('Every Saturday'));
|
||||
o.value('0', _('Every Sunday'));
|
||||
o.default = "*";
|
||||
o.depends('enable_auto_update', '1');
|
||||
|
||||
o = s.taboption('files', form.ListValue, 'auto_update_day_time', _("Update time (every day)"));
|
||||
for (var i = 0; i < 24; i++)
|
||||
o.value(i, i + ':00');
|
||||
o.default = '5';
|
||||
o.depends('enable_auto_update', '1');
|
||||
|
||||
o = s.taboption("files", form.FileUpload, "upload_conf_file", _("Upload Config File"),
|
||||
_("Upload smartdns config file to /etc/smartdns/conf.d"));
|
||||
o.rmempty = true
|
||||
@@ -870,7 +804,6 @@ return view.extend({
|
||||
s.tab("forwarding", _('DNS Forwarding Setting'));
|
||||
s.tab("block", _("DNS Block Setting"));
|
||||
s.tab("domain-rule-list", _("Domain Rule List"), _("Set Specific domain rule list."));
|
||||
s.tab("ip-rule-list", _("IP Rule List"), _("Set Specific ip rule list."));
|
||||
s.tab("domain-address", _("Domain Address"), _("Set Specific domain ip address."));
|
||||
s.tab("blackip-list", _("IP Blacklist"), _("Set Specific ip blacklist."));
|
||||
|
||||
@@ -1198,72 +1131,6 @@ return view.extend({
|
||||
});
|
||||
};
|
||||
|
||||
///////////////////////////////////////
|
||||
// ip rule list;
|
||||
///////////////////////////////////////
|
||||
o = s.taboption('ip-rule-list', form.SectionValue, '__ip-rule-list__', form.GridSection, 'ip-rule-list', _('IP Rule List'),
|
||||
_('Configure ip rule list.'));
|
||||
|
||||
ss = o.subsection;
|
||||
|
||||
ss.addremove = true;
|
||||
ss.anonymous = true;
|
||||
ss.sortable = true;
|
||||
|
||||
// enable flag;
|
||||
so = ss.option(form.Flag, "enabled", _("Enable"), _("Enable"));
|
||||
so.rmempty = false;
|
||||
so.default = so.enabled;
|
||||
so.editable = true;
|
||||
|
||||
// name;
|
||||
so = ss.option(form.Value, "name", _("IP Rule Name"), _("IP Rule Name"));
|
||||
so.rmempty = true;
|
||||
so.datatype = "string";
|
||||
|
||||
so = ss.option(form.FileUpload, "ip_set_file", _("IP Set File"), _("Upload IP set file."));
|
||||
so.rmempty = true
|
||||
so.datatype = "file"
|
||||
so.modalonly = true;
|
||||
so.root_directory = "/etc/smartdns/ip-set"
|
||||
|
||||
so = ss.option(form.DynamicList, "ip_addr", _("IP Addresses"), _("IP addresses, CIDR format."));
|
||||
so.rmempty = true;
|
||||
so.datatype = "ipaddr"
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.option(form.Flag, "whitelist_ip", _("Whitelist IP"), _("Whitelist IP Rule, Accept IP addresses within the range."));
|
||||
so.rmempty = true;
|
||||
so.default = so.disabled;
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.option(form.Flag, "blacklist_ip", _("Blacklist IP"), _("Blacklist IP Rule, Decline IP addresses within the range."));
|
||||
so.rmempty = true;
|
||||
so.default = so.disabled;
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.option(form.Flag, "ignore_ip", _("Ignore IP"), _("Do not use these IP addresses."));
|
||||
so.rmempty = true;
|
||||
so.default = so.disabled;
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.option(form.Flag, "bogus_nxdomain", _("Bogus nxdomain"), _("Return SOA when the requested result contains a specified IP address."));
|
||||
so.rmempty = true;
|
||||
so.default = so.disabled;
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.option(form.DynamicList, "ip_alias", _("IP alias"), _("IP Address Mapping, Can be used for CDN acceleration with Anycast IP, such as Cloudflare's CDN."));
|
||||
so.rmempty = true;
|
||||
so.datatype = 'ipaddr("nomask")';
|
||||
so.modalonly = true;
|
||||
|
||||
// other args
|
||||
so = ss.option(form.Value, "addition_flag", _("Additional Rule Flag"),
|
||||
_("Additional Flags for rules, read help on ip-rule for more information."))
|
||||
so.default = ""
|
||||
so.rempty = true
|
||||
so.modalonly = true;
|
||||
|
||||
////////////////
|
||||
// Support
|
||||
////////////////
|
||||
|
||||
@@ -50,14 +50,12 @@ endef
|
||||
|
||||
define Package/smartdns/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/etc/smartdns $(1)/etc/smartdns/domain-set $(1)/etc/smartdns/conf.d/ $(1)/etc/smartdns/ip-set
|
||||
$(INSTALL_DIR) $(1)/etc/smartdns $(1)/etc/smartdns/domain-set $(1)/etc/smartdns/conf.d/
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/smartdns $(1)/usr/sbin/smartdns
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/package/openwrt/files/etc/init.d/smartdns $(1)/etc/init.d/smartdns
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/address.conf $(1)/etc/smartdns/address.conf
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/blacklist-ip.conf $(1)/etc/smartdns/blacklist-ip.conf
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/custom.conf $(1)/etc/smartdns/custom.conf
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/domain-block.list $(1)/etc/smartdns/domain-block.list
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/domain-forwarding.list $(1)/etc/smartdns/domain-forwarding.list
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/files/etc/config/smartdns $(1)/etc/config/smartdns
|
||||
endef
|
||||
|
||||
|
||||
@@ -27,8 +27,6 @@ if [ ! -d "/run" ]; then
|
||||
SERVICE_PID_FILE="/var/run/smartdns.pid"
|
||||
fi
|
||||
|
||||
SMARTDNS_DEFAULT_FORWARDING_FILE="/etc/smartdns/domain-forwarding.list"
|
||||
SMARTDNS_DEFAULT_DOMAIN_BLOCK_FILE="/etc/smartdns/domain-block.list"
|
||||
SMARTDNS_CONF_DIR="/etc/smartdns"
|
||||
SMARTDNS_CONF_DOWNLOAD_DIR="$SMARTDNS_CONF_DIR/conf.d"
|
||||
SMARTDNS_DOMAIN_LIST_DOWNLOAD_DIR="$SMARTDNS_CONF_DIR/domain-set"
|
||||
@@ -126,10 +124,6 @@ clear_iptable()
|
||||
{
|
||||
local OLD_PORT="$1"
|
||||
local ipv6_server=$2
|
||||
|
||||
which iptables >/dev/null 2>&1
|
||||
[ $? -ne 0 ] && return
|
||||
|
||||
IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}')"
|
||||
for IP in $IPS
|
||||
do
|
||||
@@ -266,13 +260,13 @@ disable_auto_update()
|
||||
|
||||
enable_auto_update()
|
||||
{
|
||||
grep "0 $auto_update_day_time * * $auto_update_week_time /etc/init.d/smartdns updatefiles" /etc/crontabs/root 2>/dev/null
|
||||
grep "0 $auto_update_day_time * * * /etc/init.d/smartdns updatefiles" /etc/crontabs/root 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
disable_auto_update 1
|
||||
echo "0 $auto_update_day_time * * $auto_update_week_time /etc/init.d/smartdns updatefiles" >> /etc/crontabs/root
|
||||
echo "0 $auto_update_day_time * * * /etc/init.d/smartdns updatefiles" >> /etc/crontabs/root
|
||||
restart_crond
|
||||
}
|
||||
|
||||
@@ -302,27 +296,23 @@ load_domain_rules()
|
||||
|
||||
config_get forwarding_domain_set_file "$section" "forwarding_domain_set_file" ""
|
||||
[ ! -z "$forwarding_domain_set_file" ] && {
|
||||
[ ! -e "$forwarding_domain_set_file" ] && touch $forwarding_domain_set_file
|
||||
conf_append "domain-set" "-name ${domain_set_name}-forwarding-file -file '$forwarding_domain_set_file'"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-forwarding-file/ $domain_set_args"
|
||||
}
|
||||
|
||||
[ ! -z "$domain_set_args" ] && {
|
||||
[ ! -e "$SMARTDNS_DEFAULT_FORWARDING_FILE" ] && touch $SMARTDNS_DEFAULT_FORWARDING_FILE
|
||||
conf_append "domain-set" "-name ${domain_set_name}-forwarding-list -file $SMARTDNS_DEFAULT_FORWARDING_FILE"
|
||||
conf_append "domain-set" "-name ${domain_set_name}-forwarding-list -file /etc/smartdns/domain-forwarding.list"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-forwarding-list/ $domain_set_args"
|
||||
}
|
||||
|
||||
config_get block_domain_set_file "$section" "block_domain_set_file"
|
||||
[ ! -z "$block_domain_set_file" ] && {
|
||||
[ ! -e "$block_domain_set_file" ] && touch $block_domain_set_file
|
||||
conf_append "domain-set" "-name ${domain_set_name}-block-file -file '$block_domain_set_file'"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-block-file/ -address #"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-block-file/ --address #"
|
||||
}
|
||||
|
||||
[ ! -e "$SMARTDNS_DEFAULT_DOMAIN_BLOCK_FILE" ] && touch $SMARTDNS_DEFAULT_DOMAIN_BLOCK_FILE
|
||||
conf_append "domain-set" "-name ${domain_set_name}-block-list -file $SMARTDNS_DEFAULT_DOMAIN_BLOCK_FILE"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-block-list/ -address #"
|
||||
conf_append "domain-set" "-name ${domain_set_name}-block-list -file /etc/smartdns/domain-block.list"
|
||||
conf_append "domain-rules" "/domain-set:${domain_set_name}-block-list/ --address #"
|
||||
}
|
||||
|
||||
load_domain_rule_list()
|
||||
@@ -365,64 +355,16 @@ load_domain_rule_list()
|
||||
[ ! -z "$addition_flag" ] && domain_set_args="$domain_set_args $addition_flag"
|
||||
[ -z "$domain_set_args" ] && return
|
||||
|
||||
[ ! -e "$domain_list_file" ] && touch $domain_list_file
|
||||
conf_append "domain-set" "-name domain-rule-list-${domain_set_name} -file '$domain_list_file'"
|
||||
conf_append "domain-rules" "/domain-set:domain-rule-list-${domain_set_name}/ $domain_set_args"
|
||||
}
|
||||
|
||||
ip_rule_addr_append()
|
||||
{
|
||||
conf_append "ip-rules" "$1 $IP_set_args"
|
||||
}
|
||||
|
||||
load_IP_rule_list()
|
||||
{
|
||||
local section="$1"
|
||||
local IP_set_args=""
|
||||
local IP_set_name="$section"
|
||||
|
||||
config_get_bool enabled "$section" "enabled" "0"
|
||||
[ "$enabled" != "1" ] && return
|
||||
|
||||
config_get ip_set_file "$section" "ip_set_file" ""
|
||||
|
||||
config_get_bool whitelist_ip "$section" "whitelist_ip" "0"
|
||||
[ "$whitelist_ip" = "1" ] && IP_set_args="$IP_set_args -whitelist-ip"
|
||||
|
||||
config_get_bool blacklist_ip "$section" "blacklist_ip" "0"
|
||||
[ "$blacklist_ip" = "1" ] && IP_set_args="$IP_set_args -blacklist-ip"
|
||||
|
||||
config_get_bool ignore_ip "$section" "ignore_ip" "0"
|
||||
[ "$ignore_ip" = "1" ] && IP_set_args="$IP_set_args -ignore-ip"
|
||||
|
||||
config_get_bool bogus_nxdomain "$section" "bogus_nxdomain" "0"
|
||||
[ "$bogus_nxdomain" = "1" ] && IP_set_args="$IP_set_args -bogus-nxdomain"
|
||||
|
||||
config_get ip_alias "$section" "ip_alias" ""
|
||||
[ ! -z "$ip_alias" ] && {
|
||||
ip_alias="$(echo "$ip_alias" | sed 's/ /,/g')"
|
||||
IP_set_args="$IP_set_args -ip-alias $ip_alias"
|
||||
}
|
||||
|
||||
config_get addition_flag "$section" "addition_flag" ""
|
||||
[ ! -z "$addition_flag" ] && IP_set_args="$IP_set_args $addition_flag"
|
||||
[ -z "$IP_set_args" ] && return
|
||||
|
||||
[ ! -z "$ip_set_file" ] && [ -e "$ip_set_file" ] && {
|
||||
conf_append "ip-set" "-name ip-rule-list-file-${section} -file '$ip_set_file'"
|
||||
conf_append "ip-rules" "ip-set:ip-rule-list-file-${section} $IP_set_args"
|
||||
}
|
||||
|
||||
config_list_foreach "$section" "ip_addr" ip_rule_addr_append
|
||||
}
|
||||
|
||||
conf_append_bind()
|
||||
{
|
||||
local ADDR=""
|
||||
local bind_type="$1"
|
||||
local port="$2"
|
||||
local devices="$3"
|
||||
local device=""
|
||||
local port="$1"
|
||||
local devices="$2"
|
||||
local tcp_server="$3"
|
||||
local ipv6_server="$4"
|
||||
local ARGS="$5"
|
||||
|
||||
@@ -439,8 +381,16 @@ conf_append_bind()
|
||||
for device in $devices; do
|
||||
device="@$device"
|
||||
[ "$device" = "@-" ] && device=""
|
||||
conf_append "$bind_type" "$ADDR:$port$device $ARGS"
|
||||
conf_append "bind" "$ADDR:$port$device $ARGS"
|
||||
done
|
||||
|
||||
[ "$tcp_server" = "1" ] && {
|
||||
for device in $devices; do
|
||||
device="@$device"
|
||||
[ "$device" = "@-" ] && device=""
|
||||
conf_append "bind-tcp" "$ADDR:$port$device $ARGS"
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
load_second_server()
|
||||
@@ -498,8 +448,7 @@ load_second_server()
|
||||
config_get seconddns_server_flags "$section" "seconddns_server_flags" ""
|
||||
[ -z "$seconddns_server_flags" ] || ARGS="$ARGS $seconddns_server_flags"
|
||||
|
||||
conf_append_bind "bind" "$seconddns_port" "$device" "$ipv6_server" "$ARGS"
|
||||
[ "$seconddns_tcp_server" = "1" ] && conf_append_bind "bind-tcp" "$seconddns_port" "$device" "$ipv6_server" "$ARGS"
|
||||
conf_append_bind "$seconddns_port" "$device" "$seconddns_tcp_server" "$ipv6_server" "$ARGS"
|
||||
}
|
||||
|
||||
conf_append_conf_files()
|
||||
@@ -547,16 +496,8 @@ load_service()
|
||||
config_get port "$section" "port" "53"
|
||||
config_get ipv6_server "$section" "ipv6_server" "1"
|
||||
config_get tcp_server "$section" "tcp_server" "1"
|
||||
config_get tls_server "$section" "tls_server" "0"
|
||||
config_get tls_server_port "$section" "tls_server_port" "853"
|
||||
config_get doh_server "$section" "doh_server" "0"
|
||||
config_get doh_server_port "$section" "doh_server_port" "843"
|
||||
config_get bind_cert "$section" "bind_cert" ""
|
||||
config_get bind_cert_key "$section" "bind_cert_key" ""
|
||||
config_get bind_cert_key_pass "$section" "bind_cert_key_pass" ""
|
||||
config_get server_flags "$section" "server_flags" ""
|
||||
|
||||
config_get auto_update_week_time "$section" "auto_update_week_time" "*"
|
||||
config_get auto_update_day_time "$section" "auto_update_day_time" "5"
|
||||
|
||||
config_get speed_check_mode "$section" "speed_check_mode" ""
|
||||
@@ -710,14 +651,7 @@ load_service()
|
||||
[ "$auto_set_dnsmasq" = "0" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0"
|
||||
}
|
||||
|
||||
conf_append_bind "bind" "$port" "$device" "$ipv6_server" "$server_flags"
|
||||
[ "$tcp_server" = "1" ] && conf_append_bind "bind-tcp" "$port" "$device" "$ipv6_server" "$server_flags"
|
||||
[ "$tls_server" = "1" ] && conf_append_bind "bind-tls" "$tls_server_port" "$device" "$ipv6_server" "$server_flags"
|
||||
[ "$doh_server" = "1" ] && conf_append_bind "bind-https" "$doh_server_port" "$device" "$ipv6_server" "$server_flags"
|
||||
|
||||
[ ! -z "$bind_cert" ] && conf_append "bind-cert-file" "$bind_cert"
|
||||
[ ! -z "$bind_cert_key" ] && conf_append "bind-cert-key-file" "$bind_cert_key"
|
||||
[ ! -z "$bind_cert_key_pass" ] && conf_append "bind-cert-key-pass" "$bind_cert_key_pass"
|
||||
conf_append_bind "$port" "$device" "$tcp_server" "$ipv6_server" "$server_flags"
|
||||
|
||||
load_second_server "$section"
|
||||
|
||||
@@ -729,8 +663,6 @@ load_service()
|
||||
|
||||
config_foreach load_domain_rule_list "domain-rule-list"
|
||||
|
||||
config_foreach load_IP_rule_list "ip-rule-list"
|
||||
|
||||
{
|
||||
echo "conf-file $ADDRESS_CONF"
|
||||
echo "conf-file $BLACKLIST_IP_CONF"
|
||||
|
||||
@@ -48,7 +48,6 @@ build()
|
||||
mkdir $ROOT/root/etc/init.d -p
|
||||
mkdir $ROOT/root/etc/smartdns/ -p
|
||||
mkdir $ROOT/root/etc/smartdns/domain-set/ -p
|
||||
mkdir $ROOT/root/etc/smartdns/ip-set/ -p
|
||||
mkdir $ROOT/root/etc/smartdns/conf.d/ -p
|
||||
|
||||
cp $SMARTDNS_CONF $ROOT/root/etc/smartdns/
|
||||
|
||||
@@ -340,12 +340,9 @@ case "$1" in
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SMARTDNS_OPTION=""
|
||||
[ "$SMARTDNS_CRASH_RESTART" = "1" ] && SMARTDNS_OPTION="$SMARTDNS_OPTION -R"
|
||||
|
||||
set_smartdns_port
|
||||
get_tz
|
||||
$SMARTDNS_BIN -c "$SMARTDNS_CONF" -p $SMARTDNS_PID $SMARTDNS_OPTION
|
||||
$SMARTDNS_BIN -c "$SMARTDNS_CONF" -p $SMARTDNS_PID
|
||||
if [ $? -ne 0 ]; then
|
||||
clear_rule
|
||||
exit 1
|
||||
|
||||
@@ -5,7 +5,4 @@
|
||||
SMARTDNS_WORKMODE="1"
|
||||
|
||||
# smartdns port
|
||||
SMARTDNS_PORT="535"
|
||||
|
||||
# restart when crash
|
||||
SMARTDNS_CRASH_RESTART="1"
|
||||
SMARTDNS_PORT="535"
|
||||
@@ -15,8 +15,8 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
BIN=smartdns
|
||||
OBJS_LIB=lib/rbtree.o lib/art.o lib/bitops.o lib/radix.o lib/timer_wheel.o lib/idna.o lib/conf.o lib/nftset.o
|
||||
OBJS_MAIN=smartdns.o fast_ping.o dns_client.o dns_server.o dns.o util.o tlog.o dns_conf.o dns_cache.o http_parse.o proxy.o timer.o
|
||||
OBJS_LIB=lib/rbtree.o lib/art.o lib/bitops.o lib/radix.o lib/timer_wheel.o
|
||||
OBJS_MAIN=smartdns.o fast_ping.o dns_client.o dns_server.o dns.o util.o tlog.o dns_conf.o dns_cache.o http_parse.o proxy.o timer.o lib/conf.o lib/nftset.o
|
||||
OBJS=$(OBJS_MAIN) $(OBJS_LIB)
|
||||
|
||||
# cflags
|
||||
@@ -28,7 +28,7 @@ ifndef CFLAGS
|
||||
endif
|
||||
CFLAGS +=-Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing -funwind-tables -Wmissing-prototypes -Wshadow -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough
|
||||
endif
|
||||
override CFLAGS +=-Iinclude -I/home/rock/code/build/openssl/openssl-3.2.0/include
|
||||
override CFLAGS +=-Iinclude
|
||||
override CFLAGS += -DBASE_FILE_NAME='"$(notdir $<)"'
|
||||
override CFLAGS += $(EXTRA_CFLAGS)
|
||||
ifdef VER
|
||||
@@ -40,7 +40,7 @@ override CXXFLAGS +=-Iinclude
|
||||
|
||||
# ldflags
|
||||
ifeq ($(STATIC), yes)
|
||||
override LDFLAGS += -lssl -lcrypto -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -ldl -static -L/home/rock/code/build/openssl/openssl-3.2.0
|
||||
override LDFLAGS += -lssl -lcrypto -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -ldl -static
|
||||
else
|
||||
override LDFLAGS += -lssl -lcrypto -lpthread -ldl
|
||||
endif
|
||||
|
||||
191
src/dns.c
191
src/dns.c
@@ -738,14 +738,14 @@ static int _dns_add_opt_RAW(struct dns_packet *packet, dns_opt_code_t opt_rrtype
|
||||
struct dns_opt *opt = (struct dns_opt *)opt_data;
|
||||
int len = 0;
|
||||
|
||||
opt->code = opt_rrtype;
|
||||
opt->code = DNS_OPT_T_TCP_KEEPALIVE;
|
||||
opt->length = sizeof(unsigned short);
|
||||
|
||||
memcpy(opt->data, raw, raw_len);
|
||||
len += raw_len;
|
||||
len += sizeof(*opt);
|
||||
|
||||
return _dns_add_RAW(packet, DNS_RRS_OPT, (dns_type_t)opt_rrtype, "", 0, opt_data, len);
|
||||
return _dns_add_RAW(packet, DNS_RRS_OPT, (dns_type_t)DNS_OPT_T_TCP_KEEPALIVE, "", 0, opt_data, len);
|
||||
}
|
||||
|
||||
static int _dns_get_opt_RAW(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct dns_opt *dns_opt,
|
||||
@@ -1030,7 +1030,7 @@ int dns_add_OPT_ECS(struct dns_packet *packet, struct dns_opt_ecs *ecs)
|
||||
return _dns_add_RAW(packet, DNS_RRS_OPT, (dns_type_t)DNS_OPT_T_ECS, "", 0, opt_data, len);
|
||||
}
|
||||
|
||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, struct dns_opt_ecs *ecs)
|
||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs)
|
||||
{
|
||||
unsigned char opt_data[DNS_MAX_OPT_LEN];
|
||||
char domain[DNS_MAX_CNAME_LEN] = {0};
|
||||
@@ -1067,16 +1067,16 @@ int dns_add_OPT_TCP_KEEPALIVE(struct dns_packet *packet, unsigned short timeout)
|
||||
return _dns_add_opt_RAW(packet, DNS_OPT_T_TCP_KEEPALIVE, &timeout_net, data_len);
|
||||
}
|
||||
|
||||
int dns_get_OPT_TCP_KEEPALIVE(struct dns_rrs *rrs, unsigned short *timeout)
|
||||
int dns_get_OPT_TCP_KEEPALIVE(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len,
|
||||
unsigned short *timeout)
|
||||
{
|
||||
unsigned char opt_data[DNS_MAX_OPT_LEN];
|
||||
char domain[DNS_MAX_CNAME_LEN] = {0};
|
||||
struct dns_opt *opt = (struct dns_opt *)opt_data;
|
||||
int len = DNS_MAX_OPT_LEN;
|
||||
int ttl = 0;
|
||||
unsigned char *data = NULL;
|
||||
|
||||
if (_dns_get_opt_RAW(rrs, domain, DNS_MAX_CNAME_LEN, &ttl, opt, &len) != 0) {
|
||||
if (_dns_get_opt_RAW(rrs, NULL, 0, &ttl, opt, &len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1104,60 +1104,6 @@ int dns_get_OPT_TCP_KEEPALIVE(struct dns_rrs *rrs, unsigned short *timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_add_SRV(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, int priority, int weight,
|
||||
int port, const char *target)
|
||||
{
|
||||
unsigned char data[DNS_MAX_CNAME_LEN];
|
||||
unsigned char *data_ptr = data;
|
||||
|
||||
int target_len = 0;
|
||||
if (target == NULL) {
|
||||
target = "";
|
||||
}
|
||||
|
||||
target_len = strnlen(target, DNS_MAX_CNAME_LEN) + 1;
|
||||
memcpy(data_ptr, &priority, sizeof(unsigned short));
|
||||
data_ptr += sizeof(unsigned short);
|
||||
memcpy(data_ptr, &weight, sizeof(unsigned short));
|
||||
data_ptr += sizeof(unsigned short);
|
||||
memcpy(data_ptr, &port, sizeof(unsigned short));
|
||||
data_ptr += sizeof(unsigned short);
|
||||
if (data_ptr - data + target_len >= DNS_MAX_CNAME_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
safe_strncpy((char *)data_ptr, target, target_len);
|
||||
data_ptr += target_len;
|
||||
|
||||
return _dns_add_RAW(packet, type, DNS_T_SRV, domain, ttl, data, data_ptr - data);
|
||||
}
|
||||
|
||||
int dns_get_SRV(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned short *priority,
|
||||
unsigned short *weight, unsigned short *port, char *target, int target_size)
|
||||
{
|
||||
unsigned char data[DNS_MAX_CNAME_LEN];
|
||||
unsigned char *ptr = data;
|
||||
int len = sizeof(data);
|
||||
|
||||
if (_dns_get_RAW(rrs, domain, maxsize, ttl, data, &len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len < 6) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(priority, ptr, sizeof(unsigned short));
|
||||
ptr += sizeof(unsigned short);
|
||||
memcpy(weight, ptr, sizeof(unsigned short));
|
||||
ptr += sizeof(unsigned short);
|
||||
memcpy(port, ptr, sizeof(unsigned short));
|
||||
ptr += sizeof(unsigned short);
|
||||
safe_strncpy(target, (char *)ptr, target_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_add_HTTPS_start(struct dns_rr_nested *svcparam_buffer, struct dns_packet *packet, dns_rr_type type,
|
||||
const char *domain, int ttl, int priority, const char *target)
|
||||
{
|
||||
@@ -1667,26 +1613,6 @@ static int _dns_encode_CNAME(struct dns_context *context, struct dns_rrs *rrs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_SRV(struct dns_context *context, unsigned short *priority, unsigned short *weight,
|
||||
unsigned short *port, char *target, int target_size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (_dns_left_len(context) < 6) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*priority = _dns_read_short(&context->ptr);
|
||||
*weight = _dns_read_short(&context->ptr);
|
||||
*port = _dns_read_short(&context->ptr);
|
||||
|
||||
ret = _dns_decode_domain(context, target, target_size);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_SOA(struct dns_context *context, struct dns_soa *soa)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1776,54 +1702,6 @@ static int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_encode_SRV(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
int ttl = 0;
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
int rr_len = 0;
|
||||
unsigned char *rr_len_ptr = NULL;
|
||||
struct dns_context data_context;
|
||||
|
||||
_dns_init_context_by_rrs(rrs, &data_context);
|
||||
ret = _dns_get_rr_head(&data_context, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _dns_encode_rr_head(context, domain, qtype, qclass, ttl, rr_len, &rr_len_ptr);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rr_len = 0;
|
||||
|
||||
if (_dns_left_len(context) < 6) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_dns_write_short(&context->ptr, *(unsigned short *)data_context.ptr);
|
||||
data_context.ptr += 2;
|
||||
_dns_write_short(&context->ptr, *(unsigned short *)data_context.ptr);
|
||||
data_context.ptr += 2;
|
||||
_dns_write_short(&context->ptr, *(unsigned short *)data_context.ptr);
|
||||
data_context.ptr += 2;
|
||||
rr_len += 6;
|
||||
|
||||
ret = _dns_encode_domain(context, (char *)data_context.ptr);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
rr_len += ret;
|
||||
data_context.ptr += strnlen((char *)(data_context.ptr), DNS_MAX_CNAME_LEN) + 1;
|
||||
|
||||
_dns_write_short(&rr_len_ptr, rr_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_opt_ecs(struct dns_context *context, struct dns_opt_ecs *ecs, int opt_len)
|
||||
{
|
||||
int len = 0;
|
||||
@@ -1879,23 +1757,6 @@ static int _dns_decode_opt_cookie(struct dns_context *context, struct dns_opt_co
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_decode_opt_tcp_keepalive(struct dns_context *context, unsigned short *timeout, int opt_len)
|
||||
{
|
||||
if (opt_len == 0) {
|
||||
*timeout = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt_len < (int)sizeof(unsigned short)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*timeout = _dns_read_short(&context->ptr);
|
||||
|
||||
tlog(TLOG_DEBUG, "OPT TCP KEEPALIVE %u", *timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_encode_OPT(struct dns_context *context, struct dns_rrs *rrs)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -2014,7 +1875,7 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
|
||||
unsigned short opt_code = 0;
|
||||
unsigned short opt_len = 0;
|
||||
unsigned short errcode = (ttl >> 16) & 0xFFFF;
|
||||
unsigned short ever = (ttl) & 0xFFFF;
|
||||
unsigned short ever = (ttl)&0xFFFF;
|
||||
unsigned char *start = context->ptr;
|
||||
struct dns_packet *packet = context->packet;
|
||||
int ret = 0;
|
||||
@@ -2099,20 +1960,6 @@ static int _dns_decode_opt(struct dns_context *context, dns_rr_type type, unsign
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
case DNS_OPT_T_TCP_KEEPALIVE: {
|
||||
unsigned short timeout = 0;
|
||||
ret = _dns_decode_opt_tcp_keepalive(context, &timeout, opt_len);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "decode tcp keepalive failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_OPT_TCP_KEEPALIVE(packet, timeout);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "add tcp keepalive failed.");
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
case DNS_OPT_T_PADDING:
|
||||
context->ptr += opt_len;
|
||||
break;
|
||||
@@ -2399,24 +2246,6 @@ static int _dns_decode_an(struct dns_context *context, dns_rr_type type)
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
case DNS_T_SRV: {
|
||||
unsigned short priority = 0;
|
||||
unsigned short weight = 0;
|
||||
unsigned short port = 0;
|
||||
char target[DNS_MAX_CNAME_LEN];
|
||||
|
||||
ret = _dns_decode_SRV(context, &priority, &weight, &port, target, DNS_MAX_CNAME_LEN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_DEBUG, "decode SRV failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dns_add_SRV(packet, type, domain, ttl, priority, weight, port, target);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_DEBUG, "add SRV failed, %s", domain);
|
||||
return -1;
|
||||
}
|
||||
} break;
|
||||
case DNS_T_OPT: {
|
||||
unsigned char *opt_start = context->ptr;
|
||||
ret = _dns_decode_opt(context, type, ttl, rr_len);
|
||||
@@ -2533,12 +2362,6 @@ static int _dns_encode_an(struct dns_context *context, struct dns_rrs *rrs)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case DNS_T_SRV:
|
||||
ret = _dns_encode_SRV(context, rrs);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case DNS_T_HTTPS:
|
||||
ret = _dns_encode_HTTPS(context, rrs);
|
||||
if (ret < 0) {
|
||||
|
||||
10
src/dns.h
10
src/dns.h
@@ -280,15 +280,11 @@ int dns_set_OPT_payload_size(struct dns_packet *packet, int payload_size);
|
||||
int dns_get_OPT_payload_size(struct dns_packet *packet);
|
||||
|
||||
int dns_add_OPT_ECS(struct dns_packet *packet, struct dns_opt_ecs *ecs);
|
||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, struct dns_opt_ecs *ecs);
|
||||
int dns_get_OPT_ECS(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len, struct dns_opt_ecs *ecs);
|
||||
|
||||
int dns_add_OPT_TCP_KEEPALIVE(struct dns_packet *packet, unsigned short timeout);
|
||||
int dns_get_OPT_TCP_KEEPALIVE(struct dns_rrs *rrs, unsigned short *timeout);
|
||||
|
||||
int dns_add_SRV(struct dns_packet *packet, dns_rr_type type, const char *domain, int ttl, int priority, int weight,
|
||||
int port, const char *target);
|
||||
int dns_get_SRV(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned short *priority,
|
||||
unsigned short *weight, unsigned short *port, char *target, int target_size);
|
||||
int dns_get_OPT_TCP_KEEPALIVE(struct dns_rrs *rrs, unsigned short *opt_code, unsigned short *opt_len,
|
||||
unsigned short *timeout);
|
||||
|
||||
/* the key must be added in orders, or dig will report FORMERR */
|
||||
int dns_add_HTTPS_start(struct dns_rr_nested *svcparam_buffer, struct dns_packet *packet, dns_rr_type type,
|
||||
|
||||
244
src/dns_cache.c
244
src/dns_cache.c
@@ -32,8 +32,6 @@
|
||||
#define DNS_CACHE_HITNUM_STEP 3
|
||||
#define DNS_CACHE_HITNUM_STEP_MAX 6
|
||||
#define DNS_CACHE_READ_TIMEOUT 60
|
||||
#define DNS_CACHE_FAIL_TIMEOUT (60 * 5)
|
||||
#define EXPIRED_DOMAIN_PREFETCH_TIME (3600 * 8)
|
||||
|
||||
struct dns_cache_head {
|
||||
struct hash_table cache_hash;
|
||||
@@ -46,16 +44,11 @@ struct dns_cache_head {
|
||||
|
||||
typedef int (*dns_cache_read_callback)(struct dns_cache_record *cache_record, struct dns_cache_data *cache_data);
|
||||
|
||||
static int is_cache_init;
|
||||
static struct dns_cache_head dns_cache_head;
|
||||
|
||||
int dns_cache_init(int size, dns_cache_callback timeout_callback)
|
||||
{
|
||||
int bits = 0;
|
||||
if (is_cache_init == 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&dns_cache_head.cache_list);
|
||||
|
||||
bits = ilog2(size) - 1;
|
||||
@@ -71,7 +64,6 @@ int dns_cache_init(int size, dns_cache_callback timeout_callback)
|
||||
dns_cache_head.timeout_callback = timeout_callback;
|
||||
pthread_mutex_init(&dns_cache_head.lock, NULL);
|
||||
|
||||
is_cache_init = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,6 +111,11 @@ static void _dns_cache_remove(struct dns_cache *dns_cache)
|
||||
dns_cache_release(dns_cache);
|
||||
}
|
||||
|
||||
enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data)
|
||||
{
|
||||
return cache_data->head.cache_type;
|
||||
}
|
||||
|
||||
uint32_t dns_cache_get_query_flag(struct dns_cache *dns_cache)
|
||||
{
|
||||
return dns_cache->info.query_flag;
|
||||
@@ -129,6 +126,83 @@ const char *dns_cache_get_dns_group_name(struct dns_cache *dns_cache)
|
||||
return dns_cache->info.dns_group_name;
|
||||
}
|
||||
|
||||
struct dns_cache_data *dns_cache_new_data_addr(void)
|
||||
{
|
||||
struct dns_cache_addr *cache_addr = malloc(sizeof(struct dns_cache_addr));
|
||||
memset(cache_addr, 0, sizeof(struct dns_cache_addr));
|
||||
if (cache_addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cache_addr->head.cache_type = CACHE_TYPE_NONE;
|
||||
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
||||
cache_addr->head.magic = MAGIC_CACHE_DATA;
|
||||
atomic_set(&cache_addr->head.ref, 1);
|
||||
|
||||
return (struct dns_cache_data *)cache_addr;
|
||||
}
|
||||
|
||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, char *cname, int cname_ttl)
|
||||
{
|
||||
if (dns_cache == NULL) {
|
||||
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;
|
||||
if (cache_addr == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
memset(cache_addr->addr_data.addr, 0, sizeof(cache_addr->addr_data.addr));
|
||||
|
||||
if (cname) {
|
||||
safe_strncpy(cache_addr->addr_data.cname, cname, DNS_MAX_CNAME_LEN);
|
||||
cache_addr->addr_data.cname_ttl = cname_ttl;
|
||||
}
|
||||
|
||||
cache_addr->addr_data.soa = 1;
|
||||
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
||||
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
||||
errout:
|
||||
return;
|
||||
}
|
||||
|
||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, char *cname, int cname_ttl, unsigned char *addr,
|
||||
int addr_len)
|
||||
{
|
||||
if (dns_cache == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache;
|
||||
if (cache_addr == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (addr_len == DNS_RR_A_LEN) {
|
||||
memcpy(cache_addr->addr_data.addr, addr, DNS_RR_A_LEN);
|
||||
} else if (addr_len != DNS_RR_AAAA_LEN) {
|
||||
memcpy(cache_addr->addr_data.addr, addr, DNS_RR_AAAA_LEN);
|
||||
} else {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (cname) {
|
||||
safe_strncpy(cache_addr->addr_data.cname, cname, DNS_MAX_CNAME_LEN);
|
||||
cache_addr->addr_data.cname_ttl = cname_ttl;
|
||||
}
|
||||
|
||||
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
||||
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
||||
errout:
|
||||
return;
|
||||
}
|
||||
|
||||
struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len)
|
||||
{
|
||||
struct dns_cache_packet *cache_packet = NULL;
|
||||
@@ -146,6 +220,7 @@ struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len
|
||||
memcpy(cache_packet->data, packet, packet_len);
|
||||
memset(&cache_packet->head, 0, sizeof(cache_packet->head));
|
||||
|
||||
cache_packet->head.cache_type = CACHE_TYPE_PACKET;
|
||||
cache_packet->head.size = packet_len;
|
||||
cache_packet->head.magic = MAGIC_CACHE_DATA;
|
||||
atomic_set(&cache_packet->head.ref, 1);
|
||||
@@ -153,13 +228,13 @@ struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len
|
||||
return (struct dns_cache_data *)cache_packet;
|
||||
}
|
||||
|
||||
static void dns_cache_timer_release(struct tw_base *base, struct tw_timer_list *timer, void *data)
|
||||
static void dns_cache_timer_relase(struct tw_timer_list *timer, void *data)
|
||||
{
|
||||
struct dns_cache *dns_cache = data;
|
||||
dns_cache_release(dns_cache);
|
||||
}
|
||||
|
||||
static void dns_cache_expired(struct tw_base *base, struct tw_timer_list *timer, void *data, unsigned long timestamp)
|
||||
static void dns_cache_expired(struct tw_timer_list *timer, void *data, unsigned long timestamp)
|
||||
{
|
||||
struct dns_cache *dns_cache = data;
|
||||
|
||||
@@ -169,18 +244,9 @@ static void dns_cache_expired(struct tw_base *base, struct tw_timer_list *timer,
|
||||
}
|
||||
|
||||
if (dns_cache_head.timeout_callback) {
|
||||
dns_cache_tmout_action_t tmout_act = dns_cache_head.timeout_callback(dns_cache);
|
||||
switch (tmout_act) {
|
||||
case DNS_CACHE_TMOUT_ACTION_OK:
|
||||
break;
|
||||
case DNS_CACHE_TMOUT_ACTION_DEL:
|
||||
if (dns_cache_head.timeout_callback(dns_cache) != 0) {
|
||||
dns_cache_release(dns_cache);
|
||||
return;
|
||||
case DNS_CACHE_TMOUT_ACTION_RETRY:
|
||||
dns_timer_mod(&dns_cache->timer, DNS_CACHE_FAIL_TIMEOUT);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,8 +254,8 @@ static void dns_cache_expired(struct tw_base *base, struct tw_timer_list *timer,
|
||||
dns_timer_mod(&dns_cache->timer, 5);
|
||||
}
|
||||
|
||||
static int _dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int ttl, int speed, int timeout,
|
||||
int update_time, struct dns_cache_data *cache_data)
|
||||
static int _dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, int timeout, int update_time,
|
||||
struct dns_cache_data *cache_data)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache_data *old_cache_data = NULL;
|
||||
@@ -201,7 +267,7 @@ static int _dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int tt
|
||||
/* lookup existing cache */
|
||||
dns_cache = dns_cache_lookup(cache_key);
|
||||
if (dns_cache == NULL) {
|
||||
return -1;
|
||||
return dns_cache_insert(cache_key, ttl, speed, timeout, cache_data);
|
||||
}
|
||||
|
||||
if (ttl < DNS_CACHE_TTL_MIN) {
|
||||
@@ -211,7 +277,6 @@ static int _dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int tt
|
||||
/* update cache data */
|
||||
pthread_mutex_lock(&dns_cache_head.lock);
|
||||
dns_cache->del_pending = 0;
|
||||
dns_cache->info.rcode = rcode;
|
||||
dns_cache->info.qtype = cache_key->qtype;
|
||||
dns_cache->info.query_flag = cache_key->query_flag;
|
||||
dns_cache->info.ttl = ttl;
|
||||
@@ -238,10 +303,10 @@ static int _dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int tt
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int ttl, int speed, int timeout, int update_time,
|
||||
int dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, int timeout, int update_time,
|
||||
struct dns_cache_data *cache_data)
|
||||
{
|
||||
return _dns_cache_replace(cache_key, rcode, ttl, speed, timeout, update_time, cache_data);
|
||||
return _dns_cache_replace(cache_key, ttl, speed, timeout, update_time, cache_data);
|
||||
}
|
||||
|
||||
static void _dns_cache_remove_by_domain(struct dns_cache_key *cache_key)
|
||||
@@ -280,8 +345,7 @@ static void _dns_cache_remove_by_domain(struct dns_cache_key *cache_key)
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
}
|
||||
|
||||
static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data *cache_data, struct list_head *head,
|
||||
int timeout)
|
||||
static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data *cache_data, struct list_head *head)
|
||||
{
|
||||
uint32_t key = 0;
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
@@ -309,8 +373,8 @@ static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data
|
||||
dns_cache->del_pending = 0;
|
||||
dns_cache->cache_data = cache_data;
|
||||
dns_cache->timer.function = dns_cache_expired;
|
||||
dns_cache->timer.del_function = dns_cache_timer_release;
|
||||
dns_cache->timer.expires = timeout;
|
||||
dns_cache->timer.del_function = dns_cache_timer_relase;
|
||||
dns_cache->timer.expires = info->timeout;
|
||||
dns_cache->timer.data = dns_cache;
|
||||
pthread_mutex_lock(&dns_cache_head.lock);
|
||||
hash_table_add(dns_cache_head.cache_hash, &dns_cache->node, key);
|
||||
@@ -333,13 +397,13 @@ static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data
|
||||
return 0;
|
||||
errout:
|
||||
if (dns_cache) {
|
||||
dns_cache_release(dns_cache);
|
||||
free(dns_cache);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int dns_cache_insert(struct dns_cache_key *cache_key, int rcode, int ttl, int speed, int timeout,
|
||||
int dns_cache_insert(struct dns_cache_key *cache_key, int ttl, int speed, int timeout,
|
||||
struct dns_cache_data *cache_data)
|
||||
{
|
||||
struct dns_cache_info info;
|
||||
@@ -368,28 +432,10 @@ int dns_cache_insert(struct dns_cache_key *cache_key, int rcode, int ttl, int sp
|
||||
info.speed = speed;
|
||||
info.timeout = timeout;
|
||||
info.is_visited = 1;
|
||||
info.rcode = rcode;
|
||||
time(&info.insert_time);
|
||||
time(&info.replace_time);
|
||||
|
||||
return _dns_cache_insert(&info, cache_data, &dns_cache_head.cache_list, timeout);
|
||||
}
|
||||
|
||||
int dns_cache_update_timer(struct dns_cache_key *key, int timeout)
|
||||
{
|
||||
struct dns_cache *dns_cache = dns_cache_lookup(key);
|
||||
if (dns_cache == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&dns_cache_head.lock);
|
||||
dns_timer_mod(&dns_cache->timer, timeout);
|
||||
dns_cache->del_pending = 0;
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
|
||||
dns_cache_release(dns_cache);
|
||||
|
||||
return 0;
|
||||
return _dns_cache_insert(&info, cache_data, &dns_cache_head.cache_list);
|
||||
}
|
||||
|
||||
struct dns_cache *dns_cache_lookup(struct dns_cache_key *cache_key)
|
||||
@@ -456,6 +502,60 @@ int dns_cache_get_ttl(struct dns_cache *dns_cache)
|
||||
return ttl;
|
||||
}
|
||||
|
||||
int dns_cache_get_cname_ttl(struct dns_cache *dns_cache)
|
||||
{
|
||||
time_t now = 0;
|
||||
int ttl = 0;
|
||||
time(&now);
|
||||
|
||||
struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache_get_data(dns_cache);
|
||||
if (cache_addr == NULL) {
|
||||
ttl = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cache_addr->head.cache_type != CACHE_TYPE_ADDR) {
|
||||
ttl = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ttl = dns_cache->info.insert_time + cache_addr->addr_data.cname_ttl - now;
|
||||
if (ttl < 0) {
|
||||
ttl = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
int addr_ttl = dns_cache_get_ttl(dns_cache);
|
||||
if (ttl < addr_ttl && ttl < 0) {
|
||||
return addr_ttl;
|
||||
}
|
||||
|
||||
if (ttl < 0) {
|
||||
ttl = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (cache_addr) {
|
||||
dns_cache_data_put((struct dns_cache_data *)cache_addr);
|
||||
}
|
||||
|
||||
return ttl;
|
||||
}
|
||||
|
||||
int dns_cache_is_soa(struct dns_cache *dns_cache)
|
||||
{
|
||||
if (dns_cache == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dns_cache->cache_data->head.is_soa) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dns_cache_data *dns_cache_get_data(struct dns_cache *dns_cache)
|
||||
{
|
||||
struct dns_cache_data *cache_data;
|
||||
@@ -494,11 +594,6 @@ int dns_cache_is_visited(struct dns_cache *dns_cache)
|
||||
return dns_cache->info.is_visited;
|
||||
}
|
||||
|
||||
int dns_cache_total_num(void)
|
||||
{
|
||||
return atomic_read(&dns_cache_head.num);
|
||||
}
|
||||
|
||||
void dns_cache_delete(struct dns_cache *dns_cache)
|
||||
{
|
||||
pthread_mutex_lock(&dns_cache_head.lock);
|
||||
@@ -542,32 +637,21 @@ static int _dns_cache_read_to_cache(struct dns_cache_record *cache_record, struc
|
||||
struct list_head *head = NULL;
|
||||
head = &dns_cache_head.cache_list;
|
||||
struct dns_cache_info *info = &cache_record->info;
|
||||
int expired_time = 0;
|
||||
|
||||
time_t now = time(NULL);
|
||||
if (now < info->replace_time) {
|
||||
info->replace_time = now;
|
||||
}
|
||||
|
||||
expired_time = dns_conf_serve_expired_prefetch_time;
|
||||
if (expired_time == 0) {
|
||||
expired_time = dns_conf_serve_expired_ttl / 2;
|
||||
if (expired_time == 0 || expired_time > EXPIRED_DOMAIN_PREFETCH_TIME) {
|
||||
expired_time = EXPIRED_DOMAIN_PREFETCH_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int seed_tmp = now;
|
||||
int passed_time = now - info->replace_time;
|
||||
int timeout = info->timeout - passed_time;
|
||||
if ((timeout > expired_time + info->ttl) && expired_time >= 0) {
|
||||
timeout = expired_time + info->ttl;
|
||||
}
|
||||
|
||||
if (timeout < DNS_CACHE_READ_TIMEOUT * 2) {
|
||||
timeout = DNS_CACHE_READ_TIMEOUT + (rand() % DNS_CACHE_READ_TIMEOUT);
|
||||
timeout = DNS_CACHE_READ_TIMEOUT + (rand_r(&seed_tmp) % DNS_CACHE_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
if (_dns_cache_insert(&cache_record->info, cache_data, head, timeout) != 0) {
|
||||
if (timeout > dns_conf_serve_expired_ttl && dns_conf_serve_expired_ttl >= 0) {
|
||||
timeout = dns_conf_serve_expired_ttl;
|
||||
}
|
||||
info->timeout = timeout;
|
||||
|
||||
if (_dns_cache_insert(&cache_record->info, cache_data, head) != 0) {
|
||||
tlog(TLOG_ERROR, "insert cache data failed.");
|
||||
cache_data = NULL;
|
||||
goto errout;
|
||||
@@ -831,25 +915,19 @@ void dns_cache_destroy(void)
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache *tmp = NULL;
|
||||
|
||||
if (is_cache_init == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&dns_cache_head.lock);
|
||||
list_for_each_entry_safe(dns_cache, tmp, &dns_cache_head.cache_list, list)
|
||||
{
|
||||
_dns_cache_remove(dns_cache);
|
||||
_dns_cache_delete(dns_cache);
|
||||
}
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
|
||||
pthread_mutex_destroy(&dns_cache_head.lock);
|
||||
hash_table_free(dns_cache_head.cache_hash, free);
|
||||
|
||||
is_cache_init = 0;
|
||||
}
|
||||
|
||||
const char *dns_cache_file_version(void)
|
||||
{
|
||||
const char *version = "cache ver 1.3";
|
||||
const char *version = "cache ver 1.2";
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -40,8 +40,16 @@ extern "C" {
|
||||
#define MAGIC_CACHE_DATA 0x61546144
|
||||
#define MAGIC_RECORD 0x64526352
|
||||
|
||||
enum CACHE_TYPE {
|
||||
CACHE_TYPE_NONE,
|
||||
CACHE_TYPE_ADDR,
|
||||
CACHE_TYPE_PACKET,
|
||||
};
|
||||
|
||||
struct dns_cache_data_head {
|
||||
enum CACHE_TYPE cache_type;
|
||||
atomic_t ref;
|
||||
int is_soa;
|
||||
ssize_t size;
|
||||
uint32_t magic;
|
||||
};
|
||||
@@ -76,7 +84,6 @@ struct dns_cache_info {
|
||||
char dns_group_name[DNS_GROUP_NAME_LEN];
|
||||
uint32_t query_flag;
|
||||
int ttl;
|
||||
int rcode;
|
||||
int hitnum;
|
||||
int speed;
|
||||
int timeout;
|
||||
@@ -118,34 +125,25 @@ struct dns_cache_key {
|
||||
uint32_t query_flag;
|
||||
};
|
||||
|
||||
enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data);
|
||||
|
||||
uint32_t dns_cache_get_query_flag(struct dns_cache *dns_cache);
|
||||
|
||||
const char *dns_cache_get_dns_group_name(struct dns_cache *dns_cache);
|
||||
|
||||
struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len);
|
||||
|
||||
typedef enum DNS_CACHE_TMOUT_ACTION {
|
||||
DNS_CACHE_TMOUT_ACTION_OK = 0,
|
||||
DNS_CACHE_TMOUT_ACTION_DEL = 1,
|
||||
DNS_CACHE_TMOUT_ACTION_RETRY = 2,
|
||||
} dns_cache_tmout_action_t;
|
||||
|
||||
typedef dns_cache_tmout_action_t (*dns_cache_callback)(struct dns_cache *dns_cache);
|
||||
typedef int (*dns_cache_callback)(struct dns_cache *dns_cache);
|
||||
|
||||
int dns_cache_init(int size, dns_cache_callback timeout_callback);
|
||||
|
||||
int dns_cache_replace(struct dns_cache_key *key, int rcode, int ttl, int speed, int timeout, int update_time,
|
||||
int dns_cache_replace(struct dns_cache_key *key, int ttl, int speed, int tiemout, int update_time,
|
||||
struct dns_cache_data *cache_data);
|
||||
|
||||
int dns_cache_insert(struct dns_cache_key *key, int rcode, int ttl, int speed, int timeout,
|
||||
struct dns_cache_data *cache_data);
|
||||
int dns_cache_insert(struct dns_cache_key *key, int ttl, int speed, int timeout, struct dns_cache_data *cache_data);
|
||||
|
||||
struct dns_cache *dns_cache_lookup(struct dns_cache_key *key);
|
||||
|
||||
int dns_cache_total_num(void);
|
||||
|
||||
int dns_cache_update_timer(struct dns_cache_key *key, int timeout);
|
||||
|
||||
void dns_cache_delete(struct dns_cache *dns_cache);
|
||||
|
||||
void dns_cache_get(struct dns_cache *dns_cache);
|
||||
@@ -160,12 +158,23 @@ void dns_cache_update(struct dns_cache *dns_cache);
|
||||
|
||||
int dns_cache_get_ttl(struct dns_cache *dns_cache);
|
||||
|
||||
int dns_cache_get_cname_ttl(struct dns_cache *dns_cache);
|
||||
|
||||
int dns_cache_is_soa(struct dns_cache *dns_cache);
|
||||
|
||||
struct dns_cache_data *dns_cache_new_data_addr(void);
|
||||
|
||||
struct dns_cache_data *dns_cache_get_data(struct dns_cache *dns_cache);
|
||||
|
||||
void dns_cache_data_get(struct dns_cache_data *cache_data);
|
||||
|
||||
void dns_cache_data_put(struct dns_cache_data *cache_data);
|
||||
|
||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, char *cname, int cname_ttl, unsigned char *addr,
|
||||
int addr_len);
|
||||
|
||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, char *cname, int cname_ttl);
|
||||
|
||||
void dns_cache_destroy(void);
|
||||
|
||||
int dns_cache_load(const char *file);
|
||||
|
||||
325
src/dns_client.c
325
src/dns_client.c
@@ -61,7 +61,7 @@
|
||||
#define DNS_TCP_BUFFER (32 * 1024)
|
||||
#define DNS_TCP_IDLE_TIMEOUT (60 * 10)
|
||||
#define DNS_TCP_CONNECT_TIMEOUT (5)
|
||||
#define DNS_QUERY_TIMEOUT (3000)
|
||||
#define DNS_QUERY_TIMEOUT (500)
|
||||
#define DNS_QUERY_RETRY (4)
|
||||
#define DNS_PENDING_SERVER_RETRY 60
|
||||
#define SOCKET_PRIORITY (6)
|
||||
@@ -93,7 +93,7 @@ struct dns_server_info {
|
||||
/* server ping handle */
|
||||
struct ping_host_struct *ping_host;
|
||||
|
||||
char ip[DNS_MAX_HOSTNAME];
|
||||
char ip[DNS_HOSTNAME_LEN];
|
||||
int port;
|
||||
char proxy_name[DNS_HOSTNAME_LEN];
|
||||
/* server type */
|
||||
@@ -107,7 +107,6 @@ struct dns_server_info {
|
||||
int ttl_range;
|
||||
SSL *ssl;
|
||||
int ssl_write_len;
|
||||
int ssl_want_write;
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL_SESSION *ssl_session;
|
||||
|
||||
@@ -268,7 +267,7 @@ struct dns_query_struct {
|
||||
/* replied hash table */
|
||||
DECLARE_HASHTABLE(replied_map, 4);
|
||||
};
|
||||
static int is_client_init;
|
||||
|
||||
static struct dns_client client;
|
||||
static LIST_HEAD(pending_servers);
|
||||
static pthread_mutex_t pending_server_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -423,9 +422,6 @@ static const char *_dns_server_get_type_string(dns_server_type_t type)
|
||||
case DNS_SERVER_HTTPS:
|
||||
type_str = "https";
|
||||
break;
|
||||
case DNS_SERVER_QUIC:
|
||||
type_str = "quic";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -866,7 +862,6 @@ static char *_dns_client_server_get_tls_host_verify(struct dns_server_info *serv
|
||||
struct client_dns_server_flag_https *flag_https = &server_info->flags.https;
|
||||
tls_host_verify = flag_https->tls_host_verify;
|
||||
} break;
|
||||
case DNS_SERVER_QUIC:
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &server_info->flags.tls;
|
||||
tls_host_verify = flag_tls->tls_host_verify;
|
||||
@@ -899,7 +894,6 @@ static char *_dns_client_server_get_spki(struct dns_server_info *server_info, in
|
||||
spki = flag_https->spki;
|
||||
*spki_len = flag_https->spi_len;
|
||||
} break;
|
||||
case DNS_SERVER_QUIC:
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &server_info->flags.tls;
|
||||
spki = flag_tls->spki;
|
||||
@@ -960,7 +954,7 @@ static int _dns_client_set_trusted_cert(SSL_CTX *ssl_ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SSL_CTX *_ssl_ctx_get(int is_quic)
|
||||
static SSL_CTX *_ssl_ctx_get(void)
|
||||
{
|
||||
pthread_mutex_lock(&client.server_list_lock);
|
||||
SSL_CTX *ssl_ctx = client.ssl_ctx;
|
||||
@@ -970,18 +964,7 @@ static SSL_CTX *_ssl_ctx_get(int is_quic)
|
||||
}
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x30200000L)
|
||||
if (is_quic) {
|
||||
ssl_ctx = SSL_CTX_new(OSSL_QUIC_client_method());
|
||||
} else {
|
||||
ssl_ctx = SSL_CTX_new(TLS_client_method());
|
||||
}
|
||||
#else
|
||||
if (is_quic) {
|
||||
return NULL;
|
||||
}
|
||||
ssl_ctx = SSL_CTX_new(TLS_client_method());
|
||||
#endif
|
||||
#else
|
||||
ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
#endif
|
||||
@@ -1068,12 +1051,6 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
sock_type = SOCK_STREAM;
|
||||
skip_check_cert = flag_https->skip_check_cert;
|
||||
} break;
|
||||
case DNS_SERVER_QUIC: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &flags->tls;
|
||||
spki_data_len = flag_tls->spi_len;
|
||||
sock_type = SOCK_DGRAM;
|
||||
skip_check_cert = flag_tls->skip_check_cert;
|
||||
} break;
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &flags->tls;
|
||||
spki_data_len = flag_tls->spi_len;
|
||||
@@ -1146,12 +1123,8 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
}
|
||||
|
||||
/* if server type is TLS, create ssl context */
|
||||
if (server_type == DNS_SERVER_TLS || server_type == DNS_SERVER_HTTPS || server_type == DNS_SERVER_QUIC) {
|
||||
if (server_type == DNS_SERVER_QUIC) {
|
||||
server_info->ssl_ctx = _ssl_ctx_get(1);
|
||||
} else {
|
||||
server_info->ssl_ctx = _ssl_ctx_get(0);
|
||||
}
|
||||
if (server_type == DNS_SERVER_TLS || server_type == DNS_SERVER_HTTPS) {
|
||||
server_info->ssl_ctx = _ssl_ctx_get();
|
||||
if (server_info->ssl_ctx == NULL) {
|
||||
tlog(TLOG_ERROR, "init ssl failed.");
|
||||
goto errout;
|
||||
@@ -1263,7 +1236,6 @@ static void _dns_client_shutdown_socket(struct dns_server_info *server_info)
|
||||
shutdown(server_info->fd, SHUT_RDWR);
|
||||
}
|
||||
break;
|
||||
case DNS_SERVER_QUIC:
|
||||
case DNS_SERVER_TLS:
|
||||
case DNS_SERVER_HTTPS:
|
||||
if (server_info->ssl) {
|
||||
@@ -1826,7 +1798,7 @@ static int _dns_client_create_socket_udp_proxy(struct dns_server_info *server_in
|
||||
}
|
||||
|
||||
set_fd_nonblock(fd, 1);
|
||||
set_sock_keepalive(fd, 30, 3, 5);
|
||||
set_sock_keepalive(fd, 15, 3, 4);
|
||||
|
||||
ret = proxy_conn_connect(proxy);
|
||||
if (ret != 0) {
|
||||
@@ -1977,7 +1949,7 @@ static int _DNS_client_create_socket_tcp(struct dns_server_info *server_info)
|
||||
setsockopt(fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof(yes));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof(yes));
|
||||
set_sock_keepalive(fd, 30, 3, 5);
|
||||
set_sock_keepalive(fd, 15, 3, 4);
|
||||
|
||||
if (proxy) {
|
||||
ret = proxy_conn_connect(proxy);
|
||||
@@ -2025,138 +1997,6 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _DNS_client_create_socket_quic(struct dns_server_info *server_info, char *hostname)
|
||||
{
|
||||
#ifdef OSSL_QUIC1_VERSION
|
||||
int fd = 0;
|
||||
struct epoll_event event;
|
||||
SSL *ssl = NULL;
|
||||
struct proxy_conn *proxy = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (server_info->ssl_ctx == NULL) {
|
||||
tlog(TLOG_ERROR, "create ssl ctx failed, %s", server_info->ip);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (server_info->proxy_name[0] != '\0') {
|
||||
proxy = proxy_conn_new(server_info->proxy_name, server_info->ip, server_info->port, 1);
|
||||
if (proxy == NULL) {
|
||||
tlog(TLOG_ERROR, "create proxy failed, %s, proxy: %s", server_info->ip, server_info->proxy_name);
|
||||
goto errout;
|
||||
}
|
||||
fd = proxy_conn_get_fd(proxy);
|
||||
} else {
|
||||
fd = socket(server_info->ai_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
}
|
||||
|
||||
ssl = SSL_new(server_info->ssl_ctx);
|
||||
if (ssl == NULL) {
|
||||
tlog(TLOG_ERROR, "new ssl failed, %s", server_info->ip);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
tlog(TLOG_ERROR, "create socket failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (set_fd_nonblock(fd, 1) != 0) {
|
||||
tlog(TLOG_ERROR, "set socket non block failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (server_info->so_mark >= 0) {
|
||||
unsigned int so_mark = server_info->so_mark;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_MARK, &so_mark, sizeof(so_mark)) != 0) {
|
||||
tlog(TLOG_DEBUG, "set socket mark failed, %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy) {
|
||||
ret = proxy_conn_connect(proxy);
|
||||
} else {
|
||||
ret = connect(fd, &server_info->addr, server_info->ai_addrlen);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (errno != EINPROGRESS) {
|
||||
tlog(TLOG_DEBUG, "connect %s failed, %s", server_info->ip, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_set_connect_state(ssl);
|
||||
SSL_set_blocking_mode(ssl, 0);
|
||||
if (SSL_set_fd(ssl, fd) == 0) {
|
||||
tlog(TLOG_ERROR, "ssl set fd failed.");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* reuse ssl session */
|
||||
if (server_info->ssl_session) {
|
||||
SSL_set_session(ssl, server_info->ssl_session);
|
||||
}
|
||||
|
||||
SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
if (hostname[0] != 0) {
|
||||
SSL_set_tlsext_host_name(ssl, hostname);
|
||||
}
|
||||
|
||||
SSL_set1_host(ssl, hostname);
|
||||
|
||||
static const unsigned char alpn[] = {3, 'd', 'o', 'q'};
|
||||
if (SSL_set_alpn_protos(ssl, alpn, sizeof(alpn))) {
|
||||
tlog(TLOG_INFO, "SSL_set_alpn_protos failed.");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
server_info->fd = fd;
|
||||
server_info->ssl = ssl;
|
||||
server_info->ssl_write_len = -1;
|
||||
server_info->status = DNS_SERVER_STATUS_CONNECTING;
|
||||
server_info->proxy = proxy;
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.events = EPOLLIN | EPOLLOUT;
|
||||
event.data.ptr = server_info;
|
||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
|
||||
tlog(TLOG_ERROR, "epoll ctl failed.");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tlog(TLOG_DEBUG, "tls server %s connecting.\n", server_info->ip);
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
if (server_info->fd > 0) {
|
||||
server_info->fd = -1;
|
||||
}
|
||||
|
||||
if (server_info->ssl) {
|
||||
server_info->ssl = NULL;
|
||||
}
|
||||
|
||||
server_info->status = DNS_SERVER_STATUS_INIT;
|
||||
|
||||
if (fd > 0 && proxy == NULL) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (ssl) {
|
||||
SSL_free(ssl);
|
||||
}
|
||||
|
||||
if (proxy) {
|
||||
proxy_conn_free(proxy);
|
||||
}
|
||||
|
||||
return -1;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int _DNS_client_create_socket_tls(struct dns_server_info *server_info, char *hostname)
|
||||
{
|
||||
int fd = 0;
|
||||
@@ -2216,7 +2056,7 @@ static int _DNS_client_create_socket_tls(struct dns_server_info *server_info, ch
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof(yes));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof(yes));
|
||||
set_sock_keepalive(fd, 30, 3, 5);
|
||||
set_sock_keepalive(fd, 15, 3, 4);
|
||||
setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority));
|
||||
setsockopt(fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
|
||||
|
||||
@@ -2309,10 +2149,6 @@ static int _dns_client_create_socket(struct dns_server_info *server_info)
|
||||
struct client_dns_server_flag_tls *flag_tls = NULL;
|
||||
flag_tls = &server_info->flags.tls;
|
||||
return _DNS_client_create_socket_tls(server_info, flag_tls->hostname);
|
||||
} else if (server_info->type == DNS_SERVER_QUIC) {
|
||||
struct client_dns_server_flag_tls *flag_tls = NULL;
|
||||
flag_tls = &server_info->flags.tls;
|
||||
return _DNS_client_create_socket_quic(server_info, flag_tls->hostname);
|
||||
} else if (server_info->type == DNS_SERVER_HTTPS) {
|
||||
struct client_dns_server_flag_https *flag_https = NULL;
|
||||
flag_https = &server_info->flags.https;
|
||||
@@ -2538,16 +2374,16 @@ static int _dns_client_socket_ssl_send(struct dns_server_info *server, const voi
|
||||
ssl_ret = _ssl_get_error(server, ret);
|
||||
switch (ssl_ret) {
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return 0;
|
||||
break;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
case SSL_ERROR_WANT_READ:
|
||||
errno = EAGAIN;
|
||||
ret = -SSL_ERROR_WANT_READ;
|
||||
ret = -1;
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EAGAIN;
|
||||
ret = -SSL_ERROR_WANT_WRITE;
|
||||
ret = -1;
|
||||
break;
|
||||
case SSL_ERROR_SSL:
|
||||
ssl_err = ERR_get_error();
|
||||
@@ -2587,7 +2423,7 @@ static int _dns_client_socket_ssl_recv(struct dns_server_info *server, void *buf
|
||||
}
|
||||
|
||||
ret = _ssl_read(server, buf, num);
|
||||
if (ret > 0) {
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2599,11 +2435,11 @@ static int _dns_client_socket_ssl_recv(struct dns_server_info *server, void *buf
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
errno = EAGAIN;
|
||||
ret = -SSL_ERROR_WANT_READ;
|
||||
ret = -1;
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EAGAIN;
|
||||
ret = -SSL_ERROR_WANT_WRITE;
|
||||
ret = -1;
|
||||
break;
|
||||
case SSL_ERROR_SSL:
|
||||
ssl_err = ERR_get_error();
|
||||
@@ -2617,13 +2453,7 @@ static int _dns_client_socket_ssl_recv(struct dns_server_info *server, void *buf
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING
|
||||
if (ssl_reason == SSL_R_UNEXPECTED_EOF_WHILE_READING) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
tlog(TLOG_WARN, "SSL read fail error no: %s(%lx), reason: %d\n", ERR_reason_error_string(ssl_err), ssl_err, ssl_reason);
|
||||
tlog(TLOG_INFO, "SSL read fail error no: %s(%lx), len: %d\n", ERR_reason_error_string(ssl_err), ssl_err, num);
|
||||
errno = EFAULT;
|
||||
ret = -1;
|
||||
break;
|
||||
@@ -2632,6 +2462,9 @@ static int _dns_client_socket_ssl_recv(struct dns_server_info *server, void *buf
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (errno != ECONNRESET) {
|
||||
tlog(TLOG_INFO, "SSL syscall failed, %s ", strerror(errno));
|
||||
}
|
||||
ret = -1;
|
||||
return ret;
|
||||
default:
|
||||
@@ -2643,52 +2476,22 @@ static int _dns_client_socket_ssl_recv(struct dns_server_info *server, void *buf
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _dns_client_ssl_poll_event(struct dns_server_info *server_info, int ssl_ret)
|
||||
{
|
||||
struct epoll_event fd_event;
|
||||
|
||||
memset(&fd_event, 0, sizeof(fd_event));
|
||||
|
||||
if (ssl_ret == SSL_ERROR_WANT_READ) {
|
||||
fd_event.events = EPOLLIN;
|
||||
} else if (ssl_ret == SSL_ERROR_WANT_WRITE) {
|
||||
fd_event.events = EPOLLOUT | EPOLLIN;
|
||||
} else {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
fd_event.data.ptr = server_info;
|
||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_MOD, server_info->fd, &fd_event) != 0) {
|
||||
tlog(TLOG_ERROR, "epoll ctl failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _dns_client_socket_send(struct dns_server_info *server_info)
|
||||
{
|
||||
if (server_info->type == DNS_SERVER_UDP) {
|
||||
return -1;
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
return send(server_info->fd, server_info->send_buff.data, server_info->send_buff.len, MSG_NOSIGNAL);
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS ||
|
||||
server_info->type == DNS_SERVER_QUIC) {
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS) {
|
||||
int write_len = server_info->send_buff.len;
|
||||
if (server_info->ssl_write_len > 0) {
|
||||
write_len = server_info->ssl_write_len;
|
||||
server_info->ssl_write_len = -1;
|
||||
}
|
||||
server_info->ssl_want_write = 0;
|
||||
|
||||
int ret = _dns_client_socket_ssl_send(server_info, server_info->send_buff.data, write_len);
|
||||
if (ret < 0 && errno == EAGAIN) {
|
||||
server_info->ssl_write_len = write_len;
|
||||
if (_dns_client_ssl_poll_event(server_info, SSL_ERROR_WANT_WRITE) == 0) {
|
||||
errno = EAGAIN;
|
||||
if (ret != 0) {
|
||||
if (errno == EAGAIN) {
|
||||
server_info->ssl_write_len = write_len;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -2704,18 +2507,9 @@ static int _dns_client_socket_recv(struct dns_server_info *server_info)
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
return recv(server_info->fd, server_info->recv_buff.data + server_info->recv_buff.len,
|
||||
DNS_TCP_BUFFER - server_info->recv_buff.len, 0);
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS ||
|
||||
server_info->type == DNS_SERVER_QUIC) {
|
||||
int ret = _dns_client_socket_ssl_recv(server_info, server_info->recv_buff.data + server_info->recv_buff.len,
|
||||
DNS_TCP_BUFFER - server_info->recv_buff.len);
|
||||
if (ret == -SSL_ERROR_WANT_WRITE && errno == EAGAIN) {
|
||||
if (_dns_client_ssl_poll_event(server_info, SSL_ERROR_WANT_WRITE) == 0) {
|
||||
errno = EAGAIN;
|
||||
server_info->ssl_want_write = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS) {
|
||||
return _dns_client_socket_ssl_recv(server_info, server_info->recv_buff.data + server_info->recv_buff.len,
|
||||
DNS_TCP_BUFFER - server_info->recv_buff.len);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -2838,7 +2632,7 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tlog(TLOG_WARN, "recv failed, server %s:%d, %s\n", server_info->ip, server_info->port, strerror(errno));
|
||||
tlog(TLOG_ERROR, "recv failed, server %s:%d, %s\n", server_info->ip, server_info->port, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -2880,7 +2674,7 @@ static int _dns_client_process_tcp(struct dns_server_info *server_info, struct e
|
||||
server_info->status = DNS_SERVER_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
if (server_info->send_buff.len > 0 || server_info->ssl_want_write == 1) {
|
||||
if (server_info->send_buff.len > 0) {
|
||||
/* send existing send_buffer data */
|
||||
len = _dns_client_socket_send(server_info);
|
||||
if (len < 0) {
|
||||
@@ -3178,11 +2972,16 @@ static int _dns_client_process_tls(struct dns_server_info *server_info, struct e
|
||||
if (ret <= 0) {
|
||||
memset(&fd_event, 0, sizeof(fd_event));
|
||||
ssl_ret = _ssl_get_error(server_info, ret);
|
||||
if (_dns_client_ssl_poll_event(server_info, ssl_ret) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl_ret != SSL_ERROR_SYSCALL) {
|
||||
if (ssl_ret == SSL_ERROR_WANT_READ) {
|
||||
fd_event.events = EPOLLIN;
|
||||
} else if (ssl_ret == SSL_ERROR_WANT_WRITE) {
|
||||
fd_event.events = EPOLLOUT | EPOLLIN;
|
||||
} else if (ssl_ret == SSL_ERROR_SYSCALL) {
|
||||
if (errno != ENETUNREACH) {
|
||||
tlog(TLOG_WARN, "Handshake with %s failed, %s", server_info->ip, strerror(errno));
|
||||
}
|
||||
goto errout;
|
||||
} else {
|
||||
unsigned long ssl_err = ERR_get_error();
|
||||
int ssl_reason = ERR_GET_REASON(ssl_err);
|
||||
tlog(TLOG_WARN, "Handshake with %s failed, error no: %s(%d, %d, %d)\n", server_info->ip,
|
||||
@@ -3190,10 +2989,13 @@ static int _dns_client_process_tls(struct dns_server_info *server_info, struct e
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (errno != ENETUNREACH) {
|
||||
tlog(TLOG_WARN, "Handshake with %s failed, %s", server_info->ip, strerror(errno));
|
||||
fd_event.data.ptr = server_info;
|
||||
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_MOD, server_info->fd, &fd_event) != 0) {
|
||||
tlog(TLOG_ERROR, "epoll ctl failed, %s", strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
goto errout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tlog(TLOG_DEBUG, "tls server %s connected.\n", server_info->ip);
|
||||
@@ -3323,8 +3125,7 @@ static int _dns_client_process(struct dns_server_info *server_info, struct epoll
|
||||
} else if (server_info->type == DNS_SERVER_TCP) {
|
||||
/* receive from tcp */
|
||||
return _dns_client_process_tcp(server_info, event, now);
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS ||
|
||||
server_info->type == DNS_SERVER_QUIC) {
|
||||
} else if (server_info->type == DNS_SERVER_TLS || server_info->type == DNS_SERVER_HTTPS) {
|
||||
/* receive from tls */
|
||||
return _dns_client_process_tls(server_info, event, now);
|
||||
} else {
|
||||
@@ -3526,8 +3327,7 @@ static int _dns_client_send_https(struct dns_server_info *server_info, void *pac
|
||||
http_len = snprintf((char *)inpacket, DNS_IN_PACKSIZE,
|
||||
"POST %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"User-Agent: smartdns\r\n"
|
||||
"Content-Type: application/dns-message\r\n"
|
||||
"content-type: application/dns-message\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n",
|
||||
https_flag->path, https_flag->httphost, len);
|
||||
@@ -3560,11 +3360,6 @@ static int _dns_client_send_https(struct dns_server_info *server_info, void *pac
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dns_client_send_quic(struct dns_server_info *server_info, void *packet, unsigned short len)
|
||||
{
|
||||
return _dns_client_send_tls(server_info, packet, len);
|
||||
}
|
||||
|
||||
static int _dns_client_setup_server_packet(struct dns_server_info *server_info, struct dns_query_struct *query,
|
||||
void *default_packet, int default_packet_len,
|
||||
unsigned char *packet_data_buffer, void **packet_data, int *packet_data_len)
|
||||
@@ -3620,11 +3415,7 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
|
||||
}
|
||||
|
||||
dns_set_OPT_payload_size(packet, DNS_IN_PACKSIZE);
|
||||
|
||||
if (server_info->type != DNS_SERVER_UDP) {
|
||||
dns_add_OPT_TCP_KEEPALIVE(packet, 6000);
|
||||
}
|
||||
|
||||
/* dns_add_OPT_TCP_KEEPALIVE(packet, 600); */
|
||||
if ((query->qtype == DNS_T_A && server_info->ecs_ipv4.enable)) {
|
||||
dns_add_OPT_ECS(packet, &server_info->ecs_ipv4.ecs);
|
||||
} else if ((query->qtype == DNS_T_AAAA && server_info->ecs_ipv6.enable)) {
|
||||
@@ -3698,7 +3489,7 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
||||
}
|
||||
}
|
||||
total_server++;
|
||||
tlog(TLOG_DEBUG, "send query to server %s:%d", server_info->ip, server_info->port);
|
||||
tlog(TLOG_DEBUG, "send query to server %s", server_info->ip);
|
||||
if (server_info->fd <= 0) {
|
||||
ret = _dns_client_create_socket(server_info);
|
||||
if (ret != 0) {
|
||||
@@ -3738,11 +3529,6 @@ static int _dns_client_send_packet(struct dns_query_struct *query, void *packet,
|
||||
ret = _dns_client_send_https(server_info, packet_data, packet_data_len);
|
||||
send_err = errno;
|
||||
break;
|
||||
case DNS_SERVER_QUIC:
|
||||
/* quic query */
|
||||
ret = _dns_client_send_quic(server_info, packet_data, packet_data_len);
|
||||
send_err = errno;
|
||||
break;
|
||||
default:
|
||||
/* unsupported query type */
|
||||
ret = -1;
|
||||
@@ -3841,7 +3627,7 @@ static int _dns_client_send_query(struct dns_query_struct *query)
|
||||
}
|
||||
|
||||
dns_set_OPT_payload_size(packet, DNS_IN_PACKSIZE);
|
||||
/* dns_add_OPT_TCP_KEEPALIVE(packet, 1200); */
|
||||
/* dns_add_OPT_TCP_KEEPALIVE(packet, 600); */
|
||||
if (_dns_client_dns_add_ecs(query, packet) != 0) {
|
||||
tlog(TLOG_ERROR, "add ecs failed.");
|
||||
return -1;
|
||||
@@ -4575,14 +4361,12 @@ int dns_client_init(void)
|
||||
int fd_wakeup = -1;
|
||||
int ret = 0;
|
||||
|
||||
if (is_client_init == 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (client.epoll_fd > 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
srandom(time(NULL));
|
||||
|
||||
memset(&client, 0, sizeof(client));
|
||||
pthread_attr_init(&attr);
|
||||
atomic_set(&client.dns_server_num, 0);
|
||||
@@ -4626,7 +4410,6 @@ int dns_client_init(void)
|
||||
}
|
||||
|
||||
client.fd_wakeup = fd_wakeup;
|
||||
is_client_init = 1;
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
@@ -4653,10 +4436,6 @@ errout:
|
||||
|
||||
void dns_client_exit(void)
|
||||
{
|
||||
if (is_client_init == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.tid) {
|
||||
void *ret = NULL;
|
||||
atomic_set(&client.run, 0);
|
||||
@@ -4678,6 +4457,4 @@ void dns_client_exit(void)
|
||||
SSL_CTX_free(client.ssl_ctx);
|
||||
client.ssl_ctx = NULL;
|
||||
}
|
||||
|
||||
is_client_init = 0;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ typedef enum {
|
||||
DNS_SERVER_TCP,
|
||||
DNS_SERVER_TLS,
|
||||
DNS_SERVER_HTTPS,
|
||||
DNS_SERVER_QUIC,
|
||||
DNS_SERVER_TYPE_END,
|
||||
} dns_server_type_t;
|
||||
|
||||
|
||||
524
src/dns_conf.c
524
src/dns_conf.c
@@ -17,16 +17,13 @@
|
||||
*/
|
||||
|
||||
#include "dns_conf.h"
|
||||
#include "idna.h"
|
||||
#include "list.h"
|
||||
#include "rbtree.h"
|
||||
#include "tlog.h"
|
||||
#include "util.h"
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <glob.h>
|
||||
#include <libgen.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -67,9 +64,6 @@ int dns_hosts_record_num;
|
||||
/* DNS64 */
|
||||
struct dns_dns64 dns_conf_dns_dns64;
|
||||
|
||||
/* SRV-HOST */
|
||||
struct dns_srv_record_table dns_conf_srv_record_table;
|
||||
|
||||
/* server ip/port */
|
||||
struct dns_bind_ip dns_conf_bind_ip[DNS_MAX_BIND_IP];
|
||||
int dns_conf_bind_ip_num = 0;
|
||||
@@ -128,7 +122,7 @@ char dns_conf_ca_path[DNS_MAX_PATH];
|
||||
|
||||
char dns_conf_cache_file[DNS_MAX_PATH];
|
||||
int dns_conf_cache_persist = 2;
|
||||
int dns_conf_cache_checkpoint_time = DNS_DEFAULT_CHECKPOINT_TIME;
|
||||
int dns_conf_cache_checkpoint_time;
|
||||
|
||||
/* auditing */
|
||||
int dns_conf_audit_enable = 0;
|
||||
@@ -172,12 +166,6 @@ char dns_resolv_file[DNS_MAX_PATH];
|
||||
int dns_no_pidfile;
|
||||
int dns_no_daemon;
|
||||
|
||||
struct hash_table conf_file_table;
|
||||
struct conf_file_path {
|
||||
struct hlist_node node;
|
||||
char file[DNS_MAX_PATH];
|
||||
};
|
||||
|
||||
/* ECS */
|
||||
struct dns_edns_client_subnet dns_conf_ipv4_ecs;
|
||||
struct dns_edns_client_subnet dns_conf_ipv6_ecs;
|
||||
@@ -313,14 +301,8 @@ static int _get_domain(char *value, char *domain, int max_domain_size, char **pt
|
||||
goto errout;
|
||||
}
|
||||
|
||||
size_t domain_len = max_domain_size;
|
||||
domain_len = utf8_to_punycode(begin, len, domain, domain_len);
|
||||
if (domain_len <= 0) {
|
||||
tlog(TLOG_ERROR, "domain name %s invalid", value);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
domain[domain_len] = '\0';
|
||||
memcpy(domain, begin, len);
|
||||
domain[len] = '\0';
|
||||
|
||||
if (ptr_after_domain) {
|
||||
*ptr_after_domain = end + 1;
|
||||
@@ -509,26 +491,6 @@ static void _config_proxy_table_destroy(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void _config_srv_record_table_destroy(void)
|
||||
{
|
||||
struct dns_srv_records *srv_records = NULL;
|
||||
struct dns_srv_record *srv_record, *tmp1 = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
unsigned int i;
|
||||
|
||||
hash_for_each_safe(dns_conf_srv_record_table.srv, i, tmp, srv_records, node)
|
||||
{
|
||||
list_for_each_entry_safe(srv_record, tmp1, &srv_records->list, list)
|
||||
{
|
||||
list_del(&srv_record->list);
|
||||
free(srv_record);
|
||||
}
|
||||
|
||||
hlist_del_init(&srv_records->node);
|
||||
free(srv_records);
|
||||
}
|
||||
}
|
||||
|
||||
static int _config_server(int argc, char *argv[], dns_server_type_t type, int default_port)
|
||||
{
|
||||
int index = dns_conf_server_num;
|
||||
@@ -542,9 +504,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
unsigned char *spki = NULL;
|
||||
int drop_packet_latency_ms = 0;
|
||||
int is_bootstrap_dns = 0;
|
||||
char host_ip[DNS_MAX_IPLEN] = {0};
|
||||
int no_tls_host_name = 0;
|
||||
int no_tls_host_verify = 0;
|
||||
int is_hostip_set = 0;
|
||||
|
||||
int ttl = 0;
|
||||
/* clang-format off */
|
||||
@@ -601,9 +561,6 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
if (strcasecmp(scheme, "https") == 0) {
|
||||
type = DNS_SERVER_HTTPS;
|
||||
default_port = DEFAULT_DNS_HTTPS_PORT;
|
||||
} else if (strcasecmp(scheme, "quic")) {
|
||||
type = DNS_SERVER_QUIC;
|
||||
default_port = DEFAULT_DNS_QUIC_PORT;
|
||||
} else if (strcasecmp(scheme, "tls") == 0) {
|
||||
type = DNS_SERVER_TLS;
|
||||
default_port = DEFAULT_DNS_TLS_PORT;
|
||||
@@ -619,12 +576,13 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OSSL_QUIC1_VERSION
|
||||
if (type == DNS_SERVER_QUIC) {
|
||||
tlog(TLOG_ERROR, "quic not support.");
|
||||
return -1;
|
||||
if (type == DNS_SERVER_HTTPS) {
|
||||
safe_strncpy(server->hostname, server->server, sizeof(server->hostname));
|
||||
safe_strncpy(server->httphost, server->server, sizeof(server->httphost));
|
||||
if (server->path[0] == 0) {
|
||||
safe_strncpy(server->path, "/", sizeof(server->path));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if port is not defined, set port to default 53 */
|
||||
if (port == PORT_NOT_DEFINED) {
|
||||
@@ -666,7 +624,6 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
|
||||
case 'k': {
|
||||
server->skip_check_cert = 1;
|
||||
no_tls_host_verify = 1;
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
@@ -698,10 +655,10 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
break;
|
||||
}
|
||||
case 258: {
|
||||
if (check_is_ipaddr(optarg) != 0) {
|
||||
goto errout;
|
||||
if (check_is_ipaddr(server->server) != 0) {
|
||||
_conf_domain_rule_address(server->server, optarg);
|
||||
is_hostip_set = 1;
|
||||
}
|
||||
safe_strncpy(host_ip, optarg, DNS_MAX_IPLEN);
|
||||
break;
|
||||
}
|
||||
case 259: {
|
||||
@@ -712,7 +669,6 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
safe_strncpy(server->hostname, optarg, DNS_MAX_CNAME_LEN);
|
||||
if (strncmp(server->hostname, "-", 2) == 0) {
|
||||
server->hostname[0] = '\0';
|
||||
no_tls_host_name = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -722,41 +678,28 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
}
|
||||
case 262: {
|
||||
safe_strncpy(server->tls_host_verify, optarg, DNS_MAX_CNAME_LEN);
|
||||
if (strncmp(server->tls_host_verify, "-", 2) == 0) {
|
||||
server->tls_host_verify[0] = '\0';
|
||||
no_tls_host_verify = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
tlog(TLOG_WARN, "unknown server option: %s at '%s:%d'.", argv[optind - 1], conf_get_conf_file(),
|
||||
conf_get_current_lineno());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_is_ipaddr(server->server) != 0) {
|
||||
/* if server is domain name, then verify domain */
|
||||
if (server->tls_host_verify[0] == '\0' && no_tls_host_verify == 0) {
|
||||
safe_strncpy(server->tls_host_verify, server->server, DNS_MAX_CNAME_LEN);
|
||||
}
|
||||
|
||||
if (server->hostname[0] == '\0' && no_tls_host_name == 0) {
|
||||
safe_strncpy(server->hostname, server->server, DNS_MAX_CNAME_LEN);
|
||||
}
|
||||
|
||||
if (server->httphost[0] == '\0') {
|
||||
safe_strncpy(server->httphost, server->server, DNS_MAX_CNAME_LEN);
|
||||
}
|
||||
|
||||
if (host_ip[0] != '\0') {
|
||||
safe_strncpy(server->server, host_ip, DNS_MAX_IPLEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* if server is domain name, then verify domain */
|
||||
if (server->tls_host_verify[0] == '\0' && server->hostname[0] != '\0' && no_tls_host_verify == 0) {
|
||||
safe_strncpy(server->tls_host_verify, server->hostname, DNS_MAX_CNAME_LEN);
|
||||
if (server->tls_host_verify[0] == '\0' && check_is_ipaddr(server->server) != 0) {
|
||||
safe_strncpy(server->tls_host_verify, server->server, DNS_MAX_CNAME_LEN);
|
||||
}
|
||||
|
||||
/* update address rules for host-ip */
|
||||
if (is_hostip_set == 1) {
|
||||
struct dns_domain_rule *rule = _config_domain_rule_get(server->server);
|
||||
if (rule) {
|
||||
if (rule->rules[DOMAIN_RULE_ADDRESS_IPV4] != NULL && rule->rules[DOMAIN_RULE_ADDRESS_IPV6] == NULL) {
|
||||
_conf_domain_rule_address(server->server, "#6");
|
||||
} else if (rule->rules[DOMAIN_RULE_ADDRESS_IPV4] == NULL && rule->rules[DOMAIN_RULE_ADDRESS_IPV6] != NULL) {
|
||||
_conf_domain_rule_address(server->server, "#4");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add new server */
|
||||
@@ -766,17 +709,6 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
server->server_flag = server_flag;
|
||||
server->ttl = ttl;
|
||||
server->drop_packet_latency_ms = drop_packet_latency_ms;
|
||||
|
||||
if (server->type == DNS_SERVER_HTTPS) {
|
||||
if (server->path[0] == 0) {
|
||||
safe_strncpy(server->path, "/", sizeof(server->path));
|
||||
}
|
||||
|
||||
if (server->httphost[0] == '\0') {
|
||||
safe_strncpy(server->httphost, server->server, DNS_MAX_CNAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
dns_conf_server_num++;
|
||||
tlog(TLOG_DEBUG, "add server %s, flag: %X, ttl: %d", ip, result_flag, ttl);
|
||||
|
||||
@@ -861,8 +793,8 @@ static int _config_set_rule_each_from_list(const char *file, set_rule_add_func c
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (fp == NULL) {
|
||||
tlog(TLOG_ERROR, "open file %s error, %s", file, strerror(errno));
|
||||
return -1;
|
||||
tlog(TLOG_WARN, "open file %s error, %s", file, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
line_no = 0;
|
||||
@@ -912,9 +844,7 @@ static int _config_domain_rule_set_each(const char *domain_set, set_rule_add_fun
|
||||
{
|
||||
switch (set_name_item->type) {
|
||||
case DNS_DOMAIN_SET_LIST:
|
||||
if (_config_set_rule_each_from_list(set_name_item->file, callback, priv) != 0) {
|
||||
return -1;
|
||||
}
|
||||
_config_set_rule_each_from_list(set_name_item->file, callback, priv);
|
||||
break;
|
||||
case DNS_DOMAIN_SET_GEOSITE:
|
||||
break;
|
||||
@@ -982,7 +912,7 @@ static int _config_setup_domain_key(const char *domain, char *domain_key, int do
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __attribute__((unused)) struct dns_domain_rule *_config_domain_rule_get(const char *domain)
|
||||
static struct dns_domain_rule *_config_domain_rule_get(const char *domain)
|
||||
{
|
||||
char domain_key[DNS_MAX_CONF_CNAME_LEN];
|
||||
int len = 0;
|
||||
@@ -1701,9 +1631,6 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
ptr++;
|
||||
}
|
||||
continue;
|
||||
} else if (*(field) == '-') {
|
||||
if (strncmp(field, "-4", sizeof("-4")) == 0) {
|
||||
@@ -1721,9 +1648,6 @@ static int _conf_domain_rule_address(char *domain, const char *domain_address)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
ptr++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1894,122 +1818,6 @@ errout:
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dns_srv_records *dns_server_get_srv_record(const char *domain)
|
||||
{
|
||||
uint32_t key = 0;
|
||||
|
||||
key = hash_string(domain);
|
||||
struct dns_srv_records *srv_records = NULL;
|
||||
hash_for_each_possible(dns_conf_srv_record_table.srv, srv_records, node, key)
|
||||
{
|
||||
if (strncmp(srv_records->domain, domain, DNS_MAX_CONF_CNAME_LEN) == 0) {
|
||||
return srv_records;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _confg_srv_record_add(const char *domain, const char *host, unsigned short priority, unsigned short weight,
|
||||
unsigned short port)
|
||||
{
|
||||
struct dns_srv_records *srv_records = NULL;
|
||||
struct dns_srv_record *srv_record = NULL;
|
||||
uint32_t key = 0;
|
||||
|
||||
srv_records = dns_server_get_srv_record(domain);
|
||||
if (srv_records == NULL) {
|
||||
srv_records = malloc(sizeof(*srv_records));
|
||||
if (srv_records == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
memset(srv_records, 0, sizeof(*srv_records));
|
||||
safe_strncpy(srv_records->domain, domain, DNS_MAX_CONF_CNAME_LEN);
|
||||
INIT_LIST_HEAD(&srv_records->list);
|
||||
key = hash_string(domain);
|
||||
hash_add(dns_conf_srv_record_table.srv, &srv_records->node, key);
|
||||
}
|
||||
|
||||
srv_record = malloc(sizeof(*srv_record));
|
||||
if (srv_record == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
memset(srv_record, 0, sizeof(*srv_record));
|
||||
safe_strncpy(srv_record->host, host, DNS_MAX_CONF_CNAME_LEN);
|
||||
srv_record->priority = priority;
|
||||
srv_record->weight = weight;
|
||||
srv_record->port = port;
|
||||
list_add_tail(&srv_record->list, &srv_records->list);
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
if (srv_record != NULL) {
|
||||
free(srv_record);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _config_srv_record(void *data, int argc, char *argv[])
|
||||
{
|
||||
char *value = NULL;
|
||||
char domain[DNS_MAX_CONF_CNAME_LEN];
|
||||
char buff[DNS_MAX_CONF_CNAME_LEN];
|
||||
char *ptr = NULL;
|
||||
int ret = -1;
|
||||
|
||||
char *host_s;
|
||||
char *priority_s;
|
||||
char *weight_s;
|
||||
char *port_s;
|
||||
|
||||
unsigned short priority = 0;
|
||||
unsigned short weight = 0;
|
||||
unsigned short port = 1;
|
||||
|
||||
if (argc < 2) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
value = argv[1];
|
||||
if (_get_domain(value, domain, DNS_MAX_CONF_CNAME_LEN, &value) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
safe_strncpy(buff, value, sizeof(buff));
|
||||
|
||||
host_s = strtok_r(buff, ",", &ptr);
|
||||
if (host_s == NULL) {
|
||||
host_s = "";
|
||||
goto out;
|
||||
}
|
||||
|
||||
port_s = strtok_r(NULL, ",", &ptr);
|
||||
if (port_s != NULL) {
|
||||
port = atoi(port_s);
|
||||
}
|
||||
|
||||
priority_s = strtok_r(NULL, ",", &ptr);
|
||||
if (priority_s != NULL) {
|
||||
priority = atoi(priority_s);
|
||||
}
|
||||
|
||||
weight_s = strtok_r(NULL, ",", &ptr);
|
||||
if (weight_s != NULL) {
|
||||
weight = atoi(weight_s);
|
||||
}
|
||||
out:
|
||||
ret = _confg_srv_record_add(domain, host_s, priority, weight, port);
|
||||
if (ret != 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
tlog(TLOG_ERROR, "add srv-record %s:%s failed", domain, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _config_speed_check_mode_clear(struct dns_domain_check_orders *check_orders)
|
||||
{
|
||||
memset(check_orders->orders, 0, sizeof(check_orders->orders));
|
||||
@@ -2385,8 +2193,6 @@ static int _config_bind_ip(int argc, char *argv[], DNS_BIND_TYPE type)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
tlog(TLOG_WARN, "unknown bind option: %s at '%s:%d'.", argv[optind - 1], conf_get_conf_file(),
|
||||
conf_get_current_lineno());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2395,7 +2201,7 @@ static int _config_bind_ip(int argc, char *argv[], DNS_BIND_TYPE type)
|
||||
bind_ip->flags = server_flag;
|
||||
bind_ip->group = group;
|
||||
dns_conf_bind_ip_num++;
|
||||
if (bind_ip->type == DNS_BIND_TYPE_TLS || bind_ip->type == DNS_BIND_TYPE_HTTPS) {
|
||||
if (bind_ip->type == DNS_BIND_TYPE_TLS) {
|
||||
if (bind_ip->ssl_cert_file == NULL || bind_ip->ssl_cert_key_file == NULL) {
|
||||
bind_ip->ssl_cert_file = dns_conf_bind_ca_file;
|
||||
bind_ip->ssl_cert_key_file = dns_conf_bind_ca_key_file;
|
||||
@@ -2426,11 +2232,6 @@ static int _config_bind_ip_tls(void *data, int argc, char *argv[])
|
||||
return _config_bind_ip(argc, argv, DNS_BIND_TYPE_TLS);
|
||||
}
|
||||
|
||||
static int _config_bind_ip_https(void *data, int argc, char *argv[])
|
||||
{
|
||||
return _config_bind_ip(argc, argv, DNS_BIND_TYPE_HTTPS);
|
||||
}
|
||||
|
||||
static int _config_option_parser_filepath(void *data, int argc, char *argv[])
|
||||
{
|
||||
if (argc <= 1) {
|
||||
@@ -2466,14 +2267,6 @@ static int _config_server_https(void *data, int argc, char *argv[])
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _config_server_quic(void *data, int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
ret = _config_server(argc, argv, DNS_SERVER_QUIC, DEFAULT_DNS_QUIC_PORT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _conf_domain_rule_nameserver(char *domain, const char *group_name)
|
||||
{
|
||||
struct dns_nameserver_rule *nameserver_rule = NULL;
|
||||
@@ -3009,11 +2802,6 @@ static int _conf_domain_set(void *data, int argc, char *argv[])
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (access(domain_set->file, F_OK) != 0) {
|
||||
tlog(TLOG_ERROR, "domain set file %s not readable. %s", domain_set->file, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
key = hash_string(set_name);
|
||||
hash_for_each_possible(dns_domain_set_name_table.names, domain_set_name_list, node, key)
|
||||
{
|
||||
@@ -3068,9 +2856,7 @@ static int _config_ip_rule_set_each(const char *ip_set, set_rule_add_func callba
|
||||
{
|
||||
switch (set_name_item->type) {
|
||||
case DNS_IP_SET_LIST:
|
||||
if (_config_set_rule_each_from_list(set_name_item->file, callback, priv) != 0) {
|
||||
return -1;
|
||||
}
|
||||
_config_set_rule_each_from_list(set_name_item->file, callback, priv);
|
||||
break;
|
||||
default:
|
||||
tlog(TLOG_WARN, "ip set %s type %d not support.", set_name_list->name, set_name_item->type);
|
||||
@@ -3232,58 +3018,10 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _config_ip_rule_alias_add_ip(const char *ip, struct ip_rule_alias *ip_alias)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
unsigned char *paddr = NULL;
|
||||
int ret = 0;
|
||||
|
||||
ret = getaddr_by_host(ip, (struct sockaddr *)&addr, &addr_len);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "ip is invalid: %s", ip);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
paddr = (unsigned char *)&(addr_in->sin_addr.s_addr);
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
paddr = addr_in6->sin6_addr.s6_addr + 12;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} else {
|
||||
paddr = addr_in6->sin6_addr.s6_addr;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_AAAA_LEN);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
goto errout;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _config_ip_alias_add_ip_callback(const char *ip_cidr, void *priv)
|
||||
{
|
||||
return _config_ip_rule_alias_add_ip(ip_cidr, (struct ip_rule_alias *)priv);
|
||||
}
|
||||
|
||||
static int _config_ip_alias(const char *ip_cidr, const char *ips)
|
||||
{
|
||||
struct ip_rule_alias *ip_alias = NULL;
|
||||
char *target_ips = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (ip_cidr == NULL || ips == NULL) {
|
||||
goto errout;
|
||||
@@ -3294,21 +3032,43 @@ static int _config_ip_alias(const char *ip_cidr, const char *ips)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (strncmp(ips, "ip-set:", sizeof("ip-set:") - 1) == 0) {
|
||||
if (_config_ip_rule_set_each(ips + sizeof("ip-set:") - 1, _config_ip_alias_add_ip_callback, ip_alias) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
} else {
|
||||
target_ips = strdup(ips);
|
||||
if (target_ips == NULL) {
|
||||
target_ips = strdup(ips);
|
||||
if (target_ips == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
for (char *tok = strtok(target_ips, ","); tok != NULL; tok = strtok(NULL, ",")) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
unsigned char *paddr = NULL;
|
||||
int ret = 0;
|
||||
|
||||
ret = getaddr_by_host(tok, (struct sockaddr *)&addr, &addr_len);
|
||||
if (ret != 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
for (char *tok = strtok(target_ips, ","); tok != NULL; tok = strtok(NULL, ",")) {
|
||||
ret = _config_ip_rule_alias_add_ip(tok, ip_alias);
|
||||
if (ret != 0) {
|
||||
goto errout;
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *addr_in = NULL;
|
||||
addr_in = (struct sockaddr_in *)&addr;
|
||||
paddr = (unsigned char *)&(addr_in->sin_addr.s_addr);
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} break;
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *addr_in6 = NULL;
|
||||
addr_in6 = (struct sockaddr_in6 *)&addr;
|
||||
if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
|
||||
paddr = addr_in6->sin6_addr.s6_addr + 12;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_A_LEN);
|
||||
} else {
|
||||
paddr = addr_in6->sin6_addr.s6_addr;
|
||||
_dns_iplist_ip_address_add(&ip_alias->ip_alias, paddr, DNS_RR_AAAA_LEN);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
goto errout;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3317,9 +3077,7 @@ static int _config_ip_alias(const char *ip_cidr, const char *ips)
|
||||
}
|
||||
|
||||
_dns_ip_rule_put(&ip_alias->head);
|
||||
if (target_ips) {
|
||||
free(target_ips);
|
||||
}
|
||||
free(target_ips);
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
@@ -3441,8 +3199,6 @@ static int _conf_ip_rules(void *data, int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
default:
|
||||
tlog(TLOG_WARN, "unknown ip-rules option: %s at '%s:%d'.", argv[optind - 1], conf_get_conf_file(),
|
||||
conf_get_current_lineno());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3511,11 +3267,6 @@ static int _conf_ip_set(void *data, int argc, char *argv[])
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
if (access(ip_set->file, F_OK) != 0) {
|
||||
tlog(TLOG_ERROR, "ip set file %s not readable. %s", ip_set->file, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (set_name[0] == 0 || ip_set->file[0] == 0) {
|
||||
tlog(TLOG_ERROR, "invalid parameter.");
|
||||
goto errout;
|
||||
@@ -3548,10 +3299,6 @@ errout:
|
||||
if (ip_set) {
|
||||
free(ip_set);
|
||||
}
|
||||
|
||||
if (ip_set_name_list != NULL) {
|
||||
free(ip_set_name_list);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3847,8 +3594,6 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
default:
|
||||
tlog(TLOG_WARN, "unknown domain-rules option: %s at '%s:%d'.", argv[optind - 1], conf_get_conf_file(),
|
||||
conf_get_current_lineno());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4300,7 +4045,6 @@ static struct config_item _config_item[] = {
|
||||
CONF_CUSTOM("bind", _config_bind_ip_udp, NULL),
|
||||
CONF_CUSTOM("bind-tcp", _config_bind_ip_tcp, NULL),
|
||||
CONF_CUSTOM("bind-tls", _config_bind_ip_tls, NULL),
|
||||
CONF_CUSTOM("bind-https", _config_bind_ip_https, NULL),
|
||||
CONF_CUSTOM("bind-cert-file", _config_option_parser_filepath, &dns_conf_bind_ca_file),
|
||||
CONF_CUSTOM("bind-cert-key-file", _config_option_parser_filepath, &dns_conf_bind_ca_key_file),
|
||||
CONF_STRING("bind-cert-key-pass", dns_conf_bind_ca_key_pass, DNS_MAX_PATH),
|
||||
@@ -4308,12 +4052,10 @@ static struct config_item _config_item[] = {
|
||||
CONF_CUSTOM("server-tcp", _config_server_tcp, NULL),
|
||||
CONF_CUSTOM("server-tls", _config_server_tls, NULL),
|
||||
CONF_CUSTOM("server-https", _config_server_https, NULL),
|
||||
CONF_CUSTOM("server-quic", _config_server_quic, NULL),
|
||||
CONF_CUSTOM("nameserver", _config_nameserver, NULL),
|
||||
CONF_YESNO("expand-ptr-from-address", &dns_conf_expand_ptr_from_address),
|
||||
CONF_CUSTOM("address", _config_address, NULL),
|
||||
CONF_CUSTOM("cname", _config_cname, NULL),
|
||||
CONF_CUSTOM("srv-record", _config_srv_record, NULL),
|
||||
CONF_CUSTOM("proxy-server", _config_proxy_server, NULL),
|
||||
CONF_YESNO("ipset-timeout", &dns_conf_ipset_timeout_enable),
|
||||
CONF_CUSTOM("ipset", _config_ipset, NULL),
|
||||
@@ -4391,11 +4133,8 @@ static int _conf_printf(const char *file, int lineno, int ret)
|
||||
case CONF_RET_ERR:
|
||||
case CONF_RET_WARN:
|
||||
case CONF_RET_BADCONF:
|
||||
tlog(TLOG_WARN, "process config failed at '%s:%d'.", file, lineno);
|
||||
return -1;
|
||||
break;
|
||||
case CONF_RET_NOENT:
|
||||
tlog(TLOG_WARN, "unsupported config at '%s:%d'.", file, lineno);
|
||||
tlog(TLOG_WARN, "process config file '%s' failed at line %d.", file, lineno);
|
||||
syslog(LOG_NOTICE, "process config file '%s' failed at line %d.", file, lineno);
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
@@ -4405,40 +4144,17 @@ static int _conf_printf(const char *file, int lineno, int ret)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int conf_file_check_duplicate(const char *conf_file)
|
||||
{
|
||||
struct conf_file_path *file = NULL;
|
||||
uint32_t key = 0;
|
||||
|
||||
key = hash_string(conf_file);
|
||||
hash_table_for_each_possible(conf_file_table, file, node, key)
|
||||
{
|
||||
if (strncmp(file->file, conf_file, DNS_MAX_PATH) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
file = malloc(sizeof(*file));
|
||||
if (file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
safe_strncpy(file->file, conf_file, DNS_MAX_PATH);
|
||||
hash_table_add(conf_file_table, &file->node, key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int conf_additional_file(const char *conf_file)
|
||||
int config_additional_file(void *data, int argc, char *argv[])
|
||||
{
|
||||
char *conf_file = NULL;
|
||||
char file_path[DNS_MAX_PATH];
|
||||
char file_path_dir[DNS_MAX_PATH];
|
||||
|
||||
if (conf_file == NULL) {
|
||||
if (argc < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
conf_file = argv[1];
|
||||
if (conf_file[0] != '/') {
|
||||
safe_strncpy(file_path_dir, conf_get_conf_file(), DNS_MAX_PATH);
|
||||
dir_name(file_path_dir);
|
||||
@@ -4456,83 +4172,14 @@ static int conf_additional_file(const char *conf_file)
|
||||
}
|
||||
|
||||
if (access(file_path, R_OK) != 0) {
|
||||
tlog(TLOG_ERROR, "config file '%s' is not readable, %s", conf_file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conf_file_check_duplicate(file_path) == 0) {
|
||||
tlog(TLOG_WARN, "conf file %s is not readable.", file_path);
|
||||
syslog(LOG_NOTICE, "conf file %s is not readable.", file_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return load_conf(file_path, _config_item, _conf_printf);
|
||||
}
|
||||
|
||||
int config_additional_file(void *data, int argc, char *argv[])
|
||||
{
|
||||
const char *conf_pattern = NULL;
|
||||
char file_path[DNS_MAX_PATH];
|
||||
char file_path_dir[DNS_MAX_PATH];
|
||||
glob_t globbuf = {0};
|
||||
|
||||
if (argc < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
conf_pattern = argv[1];
|
||||
if (conf_pattern == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conf_pattern[0] != '/') {
|
||||
safe_strncpy(file_path_dir, conf_get_conf_file(), DNS_MAX_PATH);
|
||||
dir_name(file_path_dir);
|
||||
if (strncmp(file_path_dir, conf_get_conf_file(), sizeof(file_path_dir)) == 0) {
|
||||
if (snprintf(file_path, DNS_MAX_PATH, "%s", conf_pattern) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (snprintf(file_path, DNS_MAX_PATH, "%s/%s", file_path_dir, conf_pattern) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
safe_strncpy(file_path, conf_pattern, DNS_MAX_PATH);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (glob(file_path, 0, NULL, &globbuf) != 0) {
|
||||
if (errno == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tlog(TLOG_ERROR, "open config file '%s' failed, %s", file_path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i != globbuf.gl_pathc; ++i) {
|
||||
const char *file = globbuf.gl_pathv[i];
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat(file, &statbuf) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!S_ISREG(statbuf.st_mode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (conf_additional_file(file) != 0) {
|
||||
tlog(TLOG_ERROR, "load config file '%s' failed.", file);
|
||||
globfree(&globbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *dns_conf_get_cache_dir(void)
|
||||
{
|
||||
if (dns_conf_cache_file[0] == '\0') {
|
||||
@@ -4566,7 +4213,6 @@ static int _dns_server_load_conf_init(void)
|
||||
hash_init(dns_ptr_table.ptr);
|
||||
hash_init(dns_domain_set_name_table.names);
|
||||
hash_init(dns_ip_set_name_table.names);
|
||||
hash_init(dns_conf_srv_record_table.srv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4617,7 +4263,6 @@ void dns_server_load_exit(void)
|
||||
_config_host_table_destroy(0);
|
||||
_config_qtype_soa_table_destroy();
|
||||
_config_proxy_table_destroy();
|
||||
_config_srv_record_table_destroy();
|
||||
|
||||
dns_conf_server_num = 0;
|
||||
dns_server_bind_destroy();
|
||||
@@ -4684,21 +4329,6 @@ static int _dns_ping_cap_check(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _config_file_hash_table_destroy(void)
|
||||
{
|
||||
struct conf_file_path *file = NULL;
|
||||
struct hlist_node *tmp = NULL;
|
||||
int i = 0;
|
||||
|
||||
hash_table_for_each_safe(conf_file_table, i, tmp, file, node)
|
||||
{
|
||||
hlist_del_init(&file->node);
|
||||
free(file);
|
||||
}
|
||||
|
||||
hash_table_free(conf_file_table, free);
|
||||
}
|
||||
|
||||
static int _dns_conf_load_pre(void)
|
||||
{
|
||||
if (_dns_server_load_conf_init() != 0) {
|
||||
@@ -4709,8 +4339,6 @@ static int _dns_conf_load_pre(void)
|
||||
|
||||
safe_strncpy(dns_save_fail_packet_dir, SMARTDNS_DEBUG_DIR, sizeof(dns_save_fail_packet_dir));
|
||||
|
||||
hash_table_init(conf_file_table, 8, malloc);
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
@@ -4774,8 +4402,6 @@ static int _dns_conf_load_post(void)
|
||||
|
||||
_config_add_default_server_if_needed();
|
||||
|
||||
_config_file_hash_table_destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,11 +56,9 @@ extern "C" {
|
||||
#define DEFAULT_DNS_PORT 53
|
||||
#define DEFAULT_DNS_TLS_PORT 853
|
||||
#define DEFAULT_DNS_HTTPS_PORT 443
|
||||
#define DEFAULT_DNS_QUIC_PORT 853
|
||||
#define DNS_MAX_CONF_CNAME_LEN 256
|
||||
#define MAX_QTYPE_NUM 65535
|
||||
#define DNS_MAX_REPLY_IP_NUM 8
|
||||
#define DNS_DEFAULT_CHECKPOINT_TIME (3600 * 24)
|
||||
|
||||
#define SMARTDNS_CONF_FILE "/etc/smartdns/smartdns.conf"
|
||||
#define SMARTDNS_LOG_FILE "/var/log/smartdns/smartdns.log"
|
||||
@@ -325,7 +323,7 @@ struct dns_edns_client_subnet {
|
||||
};
|
||||
|
||||
struct dns_servers {
|
||||
char server[DNS_MAX_CNAME_LEN];
|
||||
char server[DNS_MAX_IPLEN];
|
||||
unsigned short port;
|
||||
unsigned int result_flag;
|
||||
unsigned int server_flag;
|
||||
@@ -489,25 +487,6 @@ struct dns_dns64 {
|
||||
uint32_t prefix_len;
|
||||
};
|
||||
|
||||
struct dns_srv_record {
|
||||
struct list_head list;
|
||||
char host[DNS_MAX_CNAME_LEN];
|
||||
unsigned short priority;
|
||||
unsigned short weight;
|
||||
unsigned short port;
|
||||
};
|
||||
|
||||
struct dns_srv_records {
|
||||
char domain[DNS_MAX_CNAME_LEN];
|
||||
struct hlist_node node;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct dns_srv_record_table {
|
||||
DECLARE_HASHTABLE(srv, 4);
|
||||
};
|
||||
extern struct dns_srv_record_table dns_conf_srv_record_table;
|
||||
|
||||
extern struct dns_dns64 dns_conf_dns_dns64;
|
||||
|
||||
extern struct dns_bind_ip dns_conf_bind_ip[DNS_MAX_BIND_IP];
|
||||
@@ -604,8 +583,6 @@ int dns_server_check_update_hosts(void);
|
||||
|
||||
struct dns_proxy_names *dns_server_get_proxy_nams(const char *proxyname);
|
||||
|
||||
struct dns_srv_records *dns_server_get_srv_record(const char *domain);
|
||||
|
||||
extern int config_additional_file(void *data, int argc, char *argv[]);
|
||||
|
||||
const char *dns_conf_get_cache_dir(void);
|
||||
|
||||
1406
src/dns_server.c
1406
src/dns_server.c
File diff suppressed because it is too large
Load Diff
@@ -183,7 +183,6 @@ struct fast_ping_struct {
|
||||
int fake_ip_num;
|
||||
};
|
||||
|
||||
static int is_fast_ping_init;
|
||||
static struct fast_ping_struct ping;
|
||||
static atomic_t ping_sid = ATOMIC_INIT(0);
|
||||
static int bool_print_log = 1;
|
||||
@@ -2188,10 +2187,6 @@ int fast_ping_init(void)
|
||||
int ret = 0;
|
||||
bool_print_log = 1;
|
||||
|
||||
if (is_fast_ping_init == 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ping.epoll_fd > 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2237,7 +2232,6 @@ int fast_ping_init(void)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
is_fast_ping_init = 1;
|
||||
return 0;
|
||||
errout:
|
||||
if (ping.notify_tid) {
|
||||
@@ -2300,10 +2294,6 @@ static void _fast_ping_close_fds(void)
|
||||
|
||||
void fast_ping_exit(void)
|
||||
{
|
||||
if (is_fast_ping_init == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ping.notify_tid) {
|
||||
void *retval = NULL;
|
||||
atomic_set(&ping.run, 0);
|
||||
@@ -2334,6 +2324,4 @@ void fast_ping_exit(void)
|
||||
pthread_mutex_destroy(&ping.notify_lock);
|
||||
pthread_mutex_destroy(&ping.lock);
|
||||
pthread_mutex_destroy(&ping.map_lock);
|
||||
|
||||
is_fast_ping_init = 0;
|
||||
}
|
||||
|
||||
@@ -111,10 +111,10 @@ const char *http_head_get_fields_value(struct http_head *http_head, const char *
|
||||
uint32_t key;
|
||||
struct http_head_fields *filed;
|
||||
|
||||
key = hash_string_case(name);
|
||||
key = hash_string(name);
|
||||
hash_for_each_possible(http_head->field_map, filed, node, key)
|
||||
{
|
||||
if (strncasecmp(filed->name, name, 128) == 0) {
|
||||
if (strncmp(filed->name, name, 128) == 0) {
|
||||
return filed->value;
|
||||
}
|
||||
}
|
||||
@@ -205,7 +205,7 @@ static int _http_head_add_fields(struct http_head *http_head, char *name, char *
|
||||
fields->value = value;
|
||||
|
||||
list_add_tail(&fields->list, &http_head->field_head.list);
|
||||
key = hash_string_case(name);
|
||||
key = hash_string(name);
|
||||
hash_add(http_head->field_map, &fields->node, key);
|
||||
|
||||
return 0;
|
||||
@@ -384,10 +384,6 @@ int http_head_parse(struct http_head *http_head, const char *data, int data_len)
|
||||
if (http_head->head_ok == 0) {
|
||||
for (i = 0; i < data_len; i++, data++) {
|
||||
*(buff_end + i) = *data;
|
||||
if (isprint(*data) == 0 && isspace(*data) == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (*data == '\n') {
|
||||
if (http_head->buff_len + i < 2) {
|
||||
continue;
|
||||
|
||||
@@ -122,9 +122,9 @@ struct config_enum {
|
||||
.data = value, .min = min_value, .max = max_value \
|
||||
} \
|
||||
}
|
||||
#define CONF_SSIZE(key, value, min_value, max_value) \
|
||||
#define CONF_SSIZE(key, value, min_value, max_value) \
|
||||
{ \
|
||||
key, conf_ssize, &(struct config_item_ssize) \
|
||||
key, conf_ssize, &(struct config_item_ssize) \
|
||||
{ \
|
||||
.data = value, .min = min_value, .max = max_value \
|
||||
} \
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include "bitmap.h"
|
||||
#include "jhash.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* Fast hashing routine for ints, longs and pointers.
|
||||
(C) 2002 Nadia Yvette Chambers, IBM */
|
||||
@@ -224,28 +223,11 @@ static inline uint32_t hash_string_initval(const char *s, uint32_t initval)
|
||||
return h;
|
||||
}
|
||||
|
||||
static inline uint32_t hash_string_case_initval(const char *s, uint32_t initval)
|
||||
{
|
||||
uint32_t h = initval;
|
||||
|
||||
while (*s) {
|
||||
h = h * 31 + tolower(*s);
|
||||
s++;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static inline uint32_t hash_string(const char *s)
|
||||
{
|
||||
return hash_string_initval(s, 0);
|
||||
}
|
||||
|
||||
static inline uint32_t hash_string_case(const char *s)
|
||||
{
|
||||
return hash_string_case_initval(s, 0);
|
||||
}
|
||||
|
||||
static inline uint32_t hash_string_array(const char **a)
|
||||
{
|
||||
uint32_t h = 0;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||
*
|
||||
* smartdns is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* smartdns is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SMARTDNS_IDNA_H
|
||||
#define _SMARTDNS_IDNA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int utf8_to_punycode(const char *src, int src_len, char *dst, int dst_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !_SMARTDNS_IDNA_H
|
||||
@@ -21,15 +21,11 @@
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct tw_base;
|
||||
struct tw_timer_list;
|
||||
|
||||
typedef void (*tw_func)(struct tw_base *, struct tw_timer_list *, void *, unsigned long);
|
||||
typedef void (*tw_del_func)(struct tw_base *, struct tw_timer_list *, void *);
|
||||
typedef void (*tw_func)(struct tw_timer_list *, void *, unsigned long);
|
||||
typedef void (*tw_del_func)(struct tw_timer_list *, void *);
|
||||
|
||||
struct tw_timer_list {
|
||||
void *data;
|
||||
@@ -51,7 +47,4 @@ int tw_mod_timer_pending(struct tw_base *, struct tw_timer_list *, unsigned long
|
||||
|
||||
int tw_mod_timer(struct tw_base *, struct tw_timer_list *, unsigned long);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
static const char *current_conf_file = NULL;
|
||||
static int current_conf_lineno = 0;
|
||||
@@ -373,7 +372,6 @@ static int load_conf_file(const char *file, struct config_item *items, conf_erro
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "open config file '%s' failed, %s\n", file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -442,6 +440,7 @@ static int load_conf_file(const char *file, struct config_item *items, conf_erro
|
||||
}
|
||||
|
||||
if (items[i].item == NULL) {
|
||||
handler(file, line_no, CONF_RET_NOENT);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
339
src/lib/idna.c
339
src/lib/idna.c
@@ -1,339 +0,0 @@
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||
*
|
||||
* smartdns is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* smartdns is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "idna.h"
|
||||
#include <limits.h>
|
||||
|
||||
static unsigned _utf8_decode_slow(const char **p, const char *pe, unsigned a)
|
||||
{
|
||||
unsigned b;
|
||||
unsigned c;
|
||||
unsigned d;
|
||||
unsigned min;
|
||||
|
||||
if (a > 0xF7) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (pe - *p) {
|
||||
default:
|
||||
if (a > 0xEF) {
|
||||
min = 0x10000;
|
||||
a = a & 7;
|
||||
b = (unsigned char)*(*p)++;
|
||||
c = (unsigned char)*(*p)++;
|
||||
d = (unsigned char)*(*p)++;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
if (a > 0xDF) {
|
||||
min = 0x800;
|
||||
b = 0x80 | (a & 15);
|
||||
c = (unsigned char)*(*p)++;
|
||||
d = (unsigned char)*(*p)++;
|
||||
a = 0;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
if (a > 0xBF) {
|
||||
min = 0x80;
|
||||
b = 0x80;
|
||||
c = 0x80 | (a & 31);
|
||||
d = (unsigned char)*(*p)++;
|
||||
a = 0;
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0x80 != (0xC0 & (b ^ c ^ d))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
b &= 63;
|
||||
c &= 63;
|
||||
d &= 63;
|
||||
a = (a << 18) | (b << 12) | (c << 6) | d;
|
||||
|
||||
if (a < min) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a > 0x10FFFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a >= 0xD800 && a <= 0xDFFF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static unsigned _utf8_decode(const char **p, const char *pe)
|
||||
{
|
||||
unsigned a;
|
||||
|
||||
a = (unsigned char)*(*p)++;
|
||||
|
||||
if (a < 128) {
|
||||
return a;
|
||||
}
|
||||
|
||||
return _utf8_decode_slow(p, pe, a);
|
||||
}
|
||||
|
||||
static int _utf8_to_punycode_label(const char *s, const char *se, char **d, char *de)
|
||||
{
|
||||
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
const char *ss;
|
||||
unsigned c;
|
||||
unsigned h;
|
||||
unsigned k;
|
||||
unsigned n;
|
||||
unsigned m;
|
||||
unsigned q;
|
||||
unsigned t;
|
||||
unsigned x;
|
||||
unsigned y;
|
||||
unsigned bias;
|
||||
unsigned delta;
|
||||
unsigned todo;
|
||||
int first;
|
||||
|
||||
h = 0;
|
||||
ss = s;
|
||||
todo = 0;
|
||||
|
||||
while (s < se) {
|
||||
c = _utf8_decode(&s, se);
|
||||
if (c == UINT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c < 128) {
|
||||
h++;
|
||||
} else {
|
||||
todo++;
|
||||
}
|
||||
}
|
||||
|
||||
if (todo > 0) {
|
||||
if (*d < de) {
|
||||
*(*d)++ = 'x';
|
||||
}
|
||||
if (*d < de) {
|
||||
*(*d)++ = 'n';
|
||||
}
|
||||
if (*d < de) {
|
||||
*(*d)++ = '-';
|
||||
}
|
||||
if (*d < de) {
|
||||
*(*d)++ = '-';
|
||||
}
|
||||
}
|
||||
|
||||
x = 0;
|
||||
s = ss;
|
||||
while (s < se) {
|
||||
c = _utf8_decode(&s, se);
|
||||
|
||||
if (c > 127) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*d < de) {
|
||||
*(*d)++ = c;
|
||||
}
|
||||
|
||||
if (++x == h) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (todo == 0) {
|
||||
return h;
|
||||
}
|
||||
|
||||
if (h > 0) {
|
||||
if (*d < de) {
|
||||
*(*d)++ = '-';
|
||||
}
|
||||
}
|
||||
|
||||
n = 128;
|
||||
bias = 72;
|
||||
delta = 0;
|
||||
first = 1;
|
||||
|
||||
while (todo > 0) {
|
||||
m = -1;
|
||||
s = ss;
|
||||
|
||||
while (s < se) {
|
||||
c = _utf8_decode(&s, se);
|
||||
|
||||
if (c >= n) {
|
||||
if (c < m) {
|
||||
m = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x = m - n;
|
||||
y = h + 1;
|
||||
|
||||
if (x > ~delta / y) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
delta += x * y;
|
||||
n = m;
|
||||
|
||||
s = ss;
|
||||
while (s < se) {
|
||||
c = _utf8_decode(&s, se);
|
||||
|
||||
if (c < n) {
|
||||
if (++delta == 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (c != n) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (k = 36, q = delta;; k += 36) {
|
||||
t = 1;
|
||||
|
||||
if (k > bias) {
|
||||
t = k - bias;
|
||||
}
|
||||
|
||||
if (t > 26) {
|
||||
t = 26;
|
||||
}
|
||||
|
||||
if (q < t) {
|
||||
break;
|
||||
}
|
||||
|
||||
x = q - t;
|
||||
y = 36 - t;
|
||||
q = x / y;
|
||||
t = t + x % y;
|
||||
|
||||
if (*d < de) {
|
||||
*(*d)++ = alphabet[t];
|
||||
}
|
||||
}
|
||||
|
||||
if (*d < de) {
|
||||
*(*d)++ = alphabet[q];
|
||||
}
|
||||
|
||||
delta /= 2;
|
||||
|
||||
if (first) {
|
||||
delta /= 350;
|
||||
first = 0;
|
||||
}
|
||||
|
||||
h++;
|
||||
delta += delta / h;
|
||||
|
||||
for (bias = 0; delta > 35 * 26 / 2; bias += 36) {
|
||||
delta /= 35;
|
||||
}
|
||||
|
||||
bias += 36 * delta / (delta + 38);
|
||||
delta = 0;
|
||||
todo--;
|
||||
}
|
||||
|
||||
delta++;
|
||||
n++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int utf8_to_punycode(const char *src, int src_len, char *dst, int dst_len)
|
||||
{
|
||||
const char *si;
|
||||
const char *se;
|
||||
const char *st;
|
||||
unsigned c;
|
||||
char *ds;
|
||||
char *de;
|
||||
int rc;
|
||||
|
||||
ds = dst;
|
||||
si = src;
|
||||
se = src + src_len;
|
||||
de = dst + dst_len;
|
||||
|
||||
while (si < se) {
|
||||
st = si;
|
||||
c = _utf8_decode(&si, se);
|
||||
|
||||
if (c == UINT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c != '.') {
|
||||
if (c != 0x3002) {
|
||||
if (c != 0xFF0E) {
|
||||
if (c != 0xFF61) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = _utf8_to_punycode_label(src, st, &dst, de);
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (dst < de) {
|
||||
*dst++ = '.';
|
||||
}
|
||||
|
||||
src = si;
|
||||
}
|
||||
|
||||
if (src < se) {
|
||||
rc = _utf8_to_punycode_label(src, se, &dst, de);
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (dst < de) {
|
||||
*dst++ = '\0';
|
||||
}
|
||||
|
||||
return dst - ds;
|
||||
}
|
||||
@@ -34,7 +34,6 @@
|
||||
#define TVR_MASK (TVR_SIZE - 1)
|
||||
#define TVN_MASK (TVN_SIZE - 1)
|
||||
#define INDEX(N) ((base->jiffies >> (TVR_BITS + N * TVN_BITS)) & TVN_MASK)
|
||||
#define MAX_TVAL ((unsigned long)((1ULL << (TVR_BITS + 4 * TVN_BITS)) - 1))
|
||||
|
||||
struct tvec {
|
||||
struct list_head vec[TVN_SIZE];
|
||||
@@ -66,6 +65,7 @@ static inline void _tw_add_timer(struct tw_base *base, struct tw_timer_list *tim
|
||||
struct list_head *vec;
|
||||
|
||||
expires = timer->expires;
|
||||
|
||||
idx = expires - base->jiffies;
|
||||
|
||||
if (idx < TVR_SIZE) {
|
||||
@@ -80,13 +80,9 @@ static inline void _tw_add_timer(struct tw_base *base, struct tw_timer_list *tim
|
||||
} else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) {
|
||||
i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
|
||||
vec = base->tv4.vec + i;
|
||||
} else if ((signed long)idx < 0) {
|
||||
} else if ((long)idx < 0) {
|
||||
vec = base->tv1.vec + (base->jiffies & TVR_MASK);
|
||||
} else {
|
||||
if (idx > MAX_TVAL) {
|
||||
idx = MAX_TVAL;
|
||||
expires = idx + base->jiffies;
|
||||
}
|
||||
i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
|
||||
vec = base->tv5.vec + i;
|
||||
}
|
||||
@@ -94,6 +90,31 @@ static inline void _tw_add_timer(struct tw_base *base, struct tw_timer_list *tim
|
||||
list_add_tail(&timer->entry, vec);
|
||||
}
|
||||
|
||||
static inline unsigned long _apply_slack(struct tw_base *base, struct tw_timer_list *timer)
|
||||
{
|
||||
long delta;
|
||||
unsigned long mask, expires, expires_limit;
|
||||
|
||||
expires = timer->expires;
|
||||
|
||||
delta = expires - base->jiffies;
|
||||
if (delta < 256) {
|
||||
return expires;
|
||||
}
|
||||
|
||||
expires_limit = expires + delta / 256;
|
||||
mask = expires ^ expires_limit;
|
||||
if (mask == 0) {
|
||||
return expires;
|
||||
}
|
||||
|
||||
int bit = fls_long(mask);
|
||||
mask = (1UL << bit) - 1;
|
||||
|
||||
expires_limit = expires_limit & ~(mask);
|
||||
return expires_limit;
|
||||
}
|
||||
|
||||
static inline void _tw_detach_timer(struct tw_timer_list *timer)
|
||||
{
|
||||
struct list_head *entry = &timer->entry;
|
||||
@@ -158,7 +179,8 @@ void tw_add_timer(struct tw_base *base, struct tw_timer_list *timer)
|
||||
|
||||
pthread_spin_lock(&base->lock);
|
||||
{
|
||||
timer->expires += base->jiffies - 1;
|
||||
timer->expires += base->jiffies;
|
||||
timer->expires = _apply_slack(base, timer);
|
||||
_tw_add_timer(base, timer);
|
||||
}
|
||||
pthread_spin_unlock(&base->lock);
|
||||
@@ -178,7 +200,7 @@ int tw_del_timer(struct tw_base *base, struct tw_timer_list *timer)
|
||||
pthread_spin_unlock(&base->lock);
|
||||
|
||||
if (ret == 1 && timer->del_function) {
|
||||
timer->del_function(base, timer, timer->data);
|
||||
timer->del_function(timer, timer->data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -190,7 +212,9 @@ int tw_mod_timer_pending(struct tw_base *base, struct tw_timer_list *timer, unsi
|
||||
|
||||
pthread_spin_lock(&base->lock);
|
||||
{
|
||||
timer->expires = expires + base->jiffies - 1;
|
||||
timer->expires = expires + base->jiffies;
|
||||
timer->expires = _apply_slack(base, timer);
|
||||
|
||||
ret = __mod_timer(base, timer, 1);
|
||||
}
|
||||
pthread_spin_unlock(&base->lock);
|
||||
@@ -208,7 +232,8 @@ int tw_mod_timer(struct tw_base *base, struct tw_timer_list *timer, unsigned lon
|
||||
goto unblock;
|
||||
}
|
||||
|
||||
timer->expires = expires + base->jiffies - 1;
|
||||
timer->expires = expires + base->jiffies;
|
||||
timer->expires = _apply_slack(base, timer);
|
||||
|
||||
ret = __mod_timer(base, timer, 0);
|
||||
}
|
||||
@@ -276,13 +301,13 @@ static inline void run_timers(struct tw_base *base)
|
||||
_tw_detach_timer(timer);
|
||||
pthread_spin_unlock(&base->lock);
|
||||
{
|
||||
fn(base, timer, data, call_time);
|
||||
fn(timer, data, call_time);
|
||||
}
|
||||
|
||||
pthread_spin_lock(&base->lock);
|
||||
if ((timer_pending(timer) == 0 && timer->del_function)) {
|
||||
if ( (timer_pending(timer) == 0 && timer->del_function) ) {
|
||||
pthread_spin_unlock(&base->lock);
|
||||
timer->del_function(base, timer, timer->data);
|
||||
timer->del_function(timer, timer->data);
|
||||
pthread_spin_lock(&base->lock);
|
||||
}
|
||||
}
|
||||
|
||||
16
src/proxy.c
16
src/proxy.c
@@ -95,7 +95,6 @@ struct proxy_struct {
|
||||
};
|
||||
|
||||
static struct proxy_struct proxy;
|
||||
static int is_proxy_init;
|
||||
|
||||
static const char *proxy_socks5_status_code[] = {
|
||||
"success",
|
||||
@@ -1046,24 +1045,13 @@ int proxy_conn_is_udp(struct proxy_conn *proxy_conn)
|
||||
|
||||
int proxy_init(void)
|
||||
{
|
||||
if (is_proxy_init == 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&proxy, 0, sizeof(proxy));
|
||||
hash_init(proxy.proxy_server);
|
||||
is_proxy_init = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void proxy_exit(void)
|
||||
int proxy_exit(void)
|
||||
{
|
||||
if (is_proxy_init == 0) {
|
||||
return;
|
||||
}
|
||||
_proxy_remove_all();
|
||||
|
||||
is_proxy_init = 0;
|
||||
|
||||
return ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ struct proxy_conn;
|
||||
|
||||
int proxy_init(void);
|
||||
|
||||
void proxy_exit(void);
|
||||
int proxy_exit(void);
|
||||
|
||||
int proxy_add(const char *proxy_name, struct proxy_info *info);
|
||||
|
||||
|
||||
260
src/smartdns.c
260
src/smartdns.c
@@ -28,9 +28,9 @@
|
||||
#include "hashtable.h"
|
||||
#include "list.h"
|
||||
#include "rbtree.h"
|
||||
#include "timer.h"
|
||||
#include "tlog.h"
|
||||
#include "util.h"
|
||||
#include "timer.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
@@ -47,21 +47,12 @@
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <syslog.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define MAX_KEY_LEN 64
|
||||
#define SMARTDNS_PID_FILE "/run/smartdns.pid"
|
||||
#define SMARTDNS_LEGACY_PID_FILE "/var/run/smartdns.pid"
|
||||
#define TMP_BUFF_LEN_32 32
|
||||
#define SMARTDNS_CRASH_CODE 254
|
||||
|
||||
typedef enum {
|
||||
SMARTDNS_RUN_MONITOR_OK = 0,
|
||||
SMARTDNS_RUN_MONITOR_ERROR = 1,
|
||||
SMARTDNS_RUN_MONITOR_EXIT = 2,
|
||||
} smartdns_run_monitor_ret;
|
||||
|
||||
static int verbose_screen;
|
||||
|
||||
@@ -161,13 +152,12 @@ static void _help(void)
|
||||
" -f run foreground.\n"
|
||||
" -c [conf] config file.\n"
|
||||
" -p [pid] pid file path, '-' means don't create pid file.\n"
|
||||
" -R restart smartdns when crash.\n"
|
||||
" -S ignore segment fault signal.\n"
|
||||
" -x verbose screen.\n"
|
||||
" -v display version.\n"
|
||||
" -h show this help message.\n"
|
||||
|
||||
"Online help: https://pymumu.github.io/smartdns\n"
|
||||
"Online help: http://pymumu.github.io/smartdns\n"
|
||||
"Copyright (C) Nick Peng <pymumu@gmail.com>\n"
|
||||
;
|
||||
/* clang-format on */
|
||||
@@ -268,7 +258,6 @@ static int _smartdns_prepare_server_flags(struct client_dns_server_flags *flags,
|
||||
safe_strncpy(flag_http->tls_host_verify, server->tls_host_verify, sizeof(flag_http->tls_host_verify));
|
||||
flag_http->skip_check_cert = server->skip_check_cert;
|
||||
} break;
|
||||
case DNS_SERVER_QUIC:
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &flags->tls;
|
||||
flag_tls->spi_len = dns_client_spki_decode(server->spki, (unsigned char *)flag_tls->spki);
|
||||
@@ -474,29 +463,19 @@ static int _smartdns_init(void)
|
||||
int i = 0;
|
||||
char logdir[PATH_MAX] = {0};
|
||||
int logbuffersize = 0;
|
||||
int enable_log_screen = 0;
|
||||
|
||||
if (get_system_mem_size() > 1024 * 1024 * 1024) {
|
||||
logbuffersize = 1024 * 1024;
|
||||
}
|
||||
|
||||
safe_strncpy(logdir, _smartdns_log_path(), PATH_MAX);
|
||||
if (verbose_screen != 0 || dns_conf_log_console != 0 || access(dir_name(logdir), W_OK) != 0) {
|
||||
enable_log_screen = 1;
|
||||
}
|
||||
|
||||
unsigned int tlog_flag = TLOG_NONBLOCK;
|
||||
if (isatty(1) && enable_log_screen == 1) {
|
||||
tlog_flag |= TLOG_SCREEN_COLOR;
|
||||
}
|
||||
|
||||
ret = tlog_init(logfile, dns_conf_log_size, dns_conf_log_num, logbuffersize, tlog_flag);
|
||||
ret = tlog_init(logfile, dns_conf_log_size, dns_conf_log_num, logbuffersize, TLOG_NONBLOCK);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "start tlog failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (enable_log_screen) {
|
||||
safe_strncpy(logdir, _smartdns_log_path(), PATH_MAX);
|
||||
if (verbose_screen != 0 || dns_conf_log_console != 0 || access(dir_name(logdir), W_OK) != 0) {
|
||||
tlog_setlogscreen(1);
|
||||
}
|
||||
|
||||
@@ -594,6 +573,7 @@ static int _smartdns_run(void)
|
||||
|
||||
static void _smartdns_exit(void)
|
||||
{
|
||||
tlog(TLOG_INFO, "smartdns exit...");
|
||||
dns_client_exit();
|
||||
proxy_exit();
|
||||
fast_ping_exit();
|
||||
@@ -640,7 +620,7 @@ static void _sig_error_exit(int signo, siginfo_t *siginfo, void *ct)
|
||||
__DATE__, __TIME__, arch);
|
||||
print_stack();
|
||||
sleep(1);
|
||||
_exit(SMARTDNS_CRASH_CODE);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
static int sig_list[] = {SIGSEGV, SIGABRT, SIGBUS, SIGILL, SIGFPE};
|
||||
@@ -746,169 +726,6 @@ static int _smartdns_init_pre(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _smartdns_early_log(struct tlog_loginfo *loginfo, const char *format, va_list ap)
|
||||
{
|
||||
char log_buf[TLOG_MAX_LINE_LEN];
|
||||
int sys_log_level = LOG_INFO;
|
||||
int log_buf_maxlen = 0;
|
||||
|
||||
if (loginfo->level < TLOG_WARN) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_buf_maxlen = sizeof(log_buf) - 2;
|
||||
log_buf[log_buf_maxlen] = '\0';
|
||||
int len = vsnprintf(log_buf, log_buf_maxlen, format, ap);
|
||||
if (len <= 0) {
|
||||
return;
|
||||
} else if (len >= log_buf_maxlen) {
|
||||
log_buf[log_buf_maxlen - 2] = '.';
|
||||
log_buf[log_buf_maxlen - 3] = '.';
|
||||
log_buf[log_buf_maxlen - 4] = '.';
|
||||
len = log_buf_maxlen - 1;
|
||||
}
|
||||
|
||||
if (log_buf[len - 1] != '\n') {
|
||||
log_buf[len] = '\n';
|
||||
len++;
|
||||
}
|
||||
|
||||
log_buf[len] = '\0';
|
||||
|
||||
fprintf(stderr, "%s", log_buf);
|
||||
|
||||
switch (loginfo->level) {
|
||||
case TLOG_ERROR:
|
||||
sys_log_level = LOG_ERR;
|
||||
break;
|
||||
case TLOG_WARN:
|
||||
sys_log_level = LOG_WARNING;
|
||||
break;
|
||||
case TLOG_NOTICE:
|
||||
sys_log_level = LOG_NOTICE;
|
||||
break;
|
||||
case TLOG_INFO:
|
||||
sys_log_level = LOG_INFO;
|
||||
break;
|
||||
case TLOG_DEBUG:
|
||||
sys_log_level = LOG_DEBUG;
|
||||
break;
|
||||
default:
|
||||
sys_log_level = LOG_INFO;
|
||||
break;
|
||||
}
|
||||
|
||||
syslog(sys_log_level, "%s", log_buf);
|
||||
}
|
||||
|
||||
static int _smartdns_child_pid = 0;
|
||||
static int _smartdns_child_restart = 0;
|
||||
|
||||
static void _smartdns_run_monitor_sig(int sig)
|
||||
{
|
||||
if (_smartdns_child_pid > 0) {
|
||||
if (sig == SIGHUP) {
|
||||
_smartdns_child_restart = 1;
|
||||
kill(_smartdns_child_pid, SIGTERM);
|
||||
return;
|
||||
}
|
||||
kill(_smartdns_child_pid, SIGTERM);
|
||||
}
|
||||
waitpid(_smartdns_child_pid, NULL, 0);
|
||||
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
static smartdns_run_monitor_ret _smartdns_run_monitor(int restart_when_crash, int is_run_as_daemon)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
if (restart_when_crash == 0) {
|
||||
return SMARTDNS_RUN_MONITOR_OK;
|
||||
}
|
||||
|
||||
if (is_run_as_daemon) {
|
||||
switch (daemon_run(NULL)) {
|
||||
case DAEMON_RET_CHILD_OK:
|
||||
break;
|
||||
case DAEMON_RET_PARENT_OK:
|
||||
return SMARTDNS_RUN_MONITOR_EXIT;
|
||||
default:
|
||||
return SMARTDNS_RUN_MONITOR_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
daemon_kickoff(0, 1);
|
||||
|
||||
restart:
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "fork failed, %s\n", strerror(errno));
|
||||
return SMARTDNS_RUN_MONITOR_ERROR;
|
||||
} else if (pid == 0) {
|
||||
return SMARTDNS_RUN_MONITOR_OK;
|
||||
}
|
||||
|
||||
_smartdns_child_pid = pid;
|
||||
|
||||
signal(SIGTERM, _smartdns_run_monitor_sig);
|
||||
signal(SIGHUP, _smartdns_run_monitor_sig);
|
||||
while (true) {
|
||||
pid = waitpid(-1, &status, 0);
|
||||
if (pid == _smartdns_child_pid) {
|
||||
int need_restart = 0;
|
||||
char signalmsg[64] = {0};
|
||||
|
||||
if (_smartdns_child_restart == 1) {
|
||||
_smartdns_child_restart = 0;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (WEXITSTATUS(status) == SMARTDNS_CRASH_CODE) {
|
||||
need_restart = 1;
|
||||
} else if (WEXITSTATUS(status) == 255) {
|
||||
fprintf(stderr, "run daemon failed, please check log.\n");
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
switch (WTERMSIG(status)) {
|
||||
case SIGSEGV:
|
||||
case SIGABRT:
|
||||
case SIGBUS:
|
||||
case SIGILL:
|
||||
case SIGFPE:
|
||||
snprintf(signalmsg, sizeof(signalmsg), " with signal %d", WTERMSIG(status));
|
||||
need_restart = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_restart == 1) {
|
||||
printf("smartdns crashed%s, restart...\n", signalmsg);
|
||||
goto restart;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pid < 0) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
return SMARTDNS_RUN_MONITOR_ERROR;
|
||||
}
|
||||
|
||||
static void _smartdns_print_error_tip(void)
|
||||
{
|
||||
char buff[4096];
|
||||
char *log_path = realpath(_smartdns_log_path(), buff);
|
||||
|
||||
if (log_path != NULL && access(log_path, F_OK) == 0) {
|
||||
fprintf(stderr, "run daemon failed, please check log at %s\n", log_path);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
static smartdns_post_func _smartdns_post = NULL;
|
||||
@@ -951,14 +768,12 @@ int main(int argc, char *argv[])
|
||||
int opt = 0;
|
||||
char config_file[MAX_LINE_LEN];
|
||||
char pid_file[MAX_LINE_LEN];
|
||||
int is_pid_file_set = 0;
|
||||
int signal_ignore = 0;
|
||||
int restart_when_crash = getpid() == 1 ? 1 : 0;
|
||||
sigset_t empty_sigblock;
|
||||
struct stat sb;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"cache-print", required_argument, NULL, 256}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}};
|
||||
{"cache-print", required_argument, 0, 256}, {"help", no_argument, 0, 'h'}, {NULL, 0, 0, 0}};
|
||||
|
||||
safe_strncpy(config_file, SMARTDNS_CONF_FILE, MAX_LINE_LEN);
|
||||
|
||||
@@ -973,7 +788,7 @@ int main(int argc, char *argv[])
|
||||
sigprocmask(SIG_SETMASK, &empty_sigblock, NULL);
|
||||
smartdns_close_allfds();
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "fhc:p:SvxN:R", long_options, NULL)) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, "fhc:p:SvxN:", long_options, 0)) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
is_run_as_daemon = 0;
|
||||
@@ -986,12 +801,8 @@ int main(int argc, char *argv[])
|
||||
case 'p':
|
||||
if (strncmp(optarg, "-", 2) == 0 || full_path(pid_file, sizeof(pid_file), optarg) != 0) {
|
||||
snprintf(pid_file, sizeof(pid_file), "%s", optarg);
|
||||
is_pid_file_set = 1;
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
restart_when_crash = 1;
|
||||
break;
|
||||
case 'S':
|
||||
signal_ignore = 1;
|
||||
break;
|
||||
@@ -1018,44 +829,27 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
smartdns_run_monitor_ret init_ret = _smartdns_run_monitor(restart_when_crash, is_run_as_daemon);
|
||||
if (init_ret != SMARTDNS_RUN_MONITOR_OK) {
|
||||
if (init_ret == SMARTDNS_RUN_MONITOR_EXIT) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
tlog_reg_early_printf_callback(_smartdns_early_log);
|
||||
|
||||
ret = dns_server_load_conf(config_file);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "load config failed.\n");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (dns_no_daemon || restart_when_crash) {
|
||||
if (dns_no_daemon) {
|
||||
is_run_as_daemon = 0;
|
||||
}
|
||||
|
||||
if (is_run_as_daemon) {
|
||||
int child_status = -1;
|
||||
switch (daemon_run(&child_status)) {
|
||||
case DAEMON_RET_CHILD_OK:
|
||||
break;
|
||||
case DAEMON_RET_PARENT_OK: {
|
||||
if (child_status != 0 && child_status != -3) {
|
||||
_smartdns_print_error_tip();
|
||||
int daemon_ret = daemon_run();
|
||||
if (daemon_ret != -2) {
|
||||
char buff[4096];
|
||||
char *log_path = realpath(_smartdns_log_path(), buff);
|
||||
|
||||
if (log_path != NULL && access(log_path, F_OK) == 0 && daemon_ret != -3 && daemon_ret != 0) {
|
||||
fprintf(stderr, "run daemon failed, please check log at %s\n", log_path);
|
||||
}
|
||||
|
||||
return child_status;
|
||||
} break;
|
||||
case DAEMON_RET_ERR:
|
||||
default:
|
||||
fprintf(stderr, "run daemon failed.\n");
|
||||
goto errout;
|
||||
return daemon_ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1063,16 +857,6 @@ int main(int argc, char *argv[])
|
||||
_reg_signal();
|
||||
}
|
||||
|
||||
if (is_pid_file_set == 0) {
|
||||
char pid_file_path[MAX_LINE_LEN];
|
||||
safe_strncpy(pid_file_path, pid_file, MAX_LINE_LEN);
|
||||
dir_name(pid_file_path);
|
||||
|
||||
if (access(pid_file_path, W_OK) != 0) {
|
||||
dns_no_pidfile = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(pid_file, "-", 2) != 0 && dns_no_pidfile == 0 && create_pid_file(pid_file) != 0) {
|
||||
ret = -3;
|
||||
goto errout;
|
||||
@@ -1101,22 +885,16 @@ int main(int argc, char *argv[])
|
||||
if (ret != 0) {
|
||||
goto errout;
|
||||
}
|
||||
} else if (dns_conf_log_console == 0 && verbose_screen == 0) {
|
||||
daemon_close_stdfds();
|
||||
}
|
||||
|
||||
smartdns_test_notify(1);
|
||||
ret = _smartdns_run();
|
||||
tlog(TLOG_INFO, "smartdns exit...");
|
||||
_smartdns_exit();
|
||||
return ret;
|
||||
errout:
|
||||
if (is_run_as_daemon) {
|
||||
daemon_kickoff(ret, dns_conf_log_console | verbose_screen);
|
||||
} else if (dns_conf_log_console == 0 && verbose_screen == 0) {
|
||||
_smartdns_print_error_tip();
|
||||
}
|
||||
smartdns_test_notify(2);
|
||||
_smartdns_exit();
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
107
src/tlog.c
107
src/tlog.c
@@ -79,7 +79,6 @@ struct tlog_log {
|
||||
int zip_pid;
|
||||
int multi_log;
|
||||
int logscreen;
|
||||
int logscreen_color;
|
||||
int segment_log;
|
||||
int max_line_size;
|
||||
int print_errmsg;
|
||||
@@ -149,7 +148,6 @@ static struct tlog tlog;
|
||||
static int tlog_disable_early_print = 0;
|
||||
static tlog_level tlog_set_level = TLOG_INFO;
|
||||
static tlog_format_func tlog_format;
|
||||
static tlog_early_print_func tlog_early_print;
|
||||
static unsigned int tlog_localtime_lock = 0;
|
||||
|
||||
static const char *tlog_level_str[] = {
|
||||
@@ -630,7 +628,7 @@ int tlog_printf(struct tlog_log *log, const char *format, ...)
|
||||
return len;
|
||||
}
|
||||
|
||||
static int _tlog_early_print(struct tlog_info_inter *info_inter, const char *format, va_list ap)
|
||||
static int _tlog_early_print(tlog_level level, const char *file, int line, const char *func, const char *format, va_list ap)
|
||||
{
|
||||
char log_buf[TLOG_MAX_LINE_LEN];
|
||||
size_t len = 0;
|
||||
@@ -646,14 +644,9 @@ static int _tlog_early_print(struct tlog_info_inter *info_inter, const char *for
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlog_early_print != NULL) {
|
||||
tlog_early_print(&info_inter->info, format, ap);
|
||||
return out_len;
|
||||
}
|
||||
|
||||
len = snprintf(log_buf, sizeof(log_buf), "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d,%.3d][%5s][%17s:%-4d] ",
|
||||
cur_time.year, cur_time.mon, cur_time.mday, cur_time.hour, cur_time.min, cur_time.sec, cur_time.usec / 1000,
|
||||
tlog_get_level_string(info_inter->info.level), info_inter->info.file, info_inter->info.line);
|
||||
cur_time.year, cur_time.mon, cur_time.mday, cur_time.hour, cur_time.min, cur_time.sec, cur_time.usec / 1000,
|
||||
tlog_get_level_string(level), file, line);
|
||||
out_len = len;
|
||||
len = vsnprintf(log_buf + out_len, sizeof(log_buf) - out_len - 1, format, ap);
|
||||
out_len += len;
|
||||
@@ -669,7 +662,7 @@ static int _tlog_early_print(struct tlog_info_inter *info_inter, const char *for
|
||||
}
|
||||
|
||||
unused = write(STDOUT_FILENO, log_buf, out_len);
|
||||
return out_len;
|
||||
return len;
|
||||
}
|
||||
|
||||
int tlog_vext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, va_list ap)
|
||||
@@ -680,6 +673,14 @@ int tlog_vext(tlog_level level, const char *file, int line, const char *func, vo
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tlog.root == NULL) {
|
||||
return _tlog_early_print(level, file, line, func, format, ap);
|
||||
}
|
||||
|
||||
if (unlikely(tlog.root->logsize <= 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (level >= TLOG_END) {
|
||||
return -1;
|
||||
}
|
||||
@@ -693,14 +694,6 @@ int tlog_vext(tlog_level level, const char *file, int line, const char *func, vo
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlog.root == NULL) {
|
||||
return _tlog_early_print(&info_inter, format, ap);
|
||||
}
|
||||
|
||||
if (unlikely(tlog.root->logsize <= 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _tlog_vprintf(tlog.root, _tlog_root_log_buffer, &info_inter, format, ap);
|
||||
}
|
||||
|
||||
@@ -1152,54 +1145,7 @@ static void _tlog_get_log_name_dir(struct tlog_log *log)
|
||||
pthread_mutex_unlock(&tlog.lock);
|
||||
}
|
||||
|
||||
static int _tlog_write_screen(struct tlog_log *log, struct tlog_loginfo *info, const char *buff, int bufflen)
|
||||
{
|
||||
int unused __attribute__((unused));
|
||||
|
||||
if (bufflen <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (log->logscreen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (log->logscreen_color && info != NULL) {
|
||||
const char *color = NULL;
|
||||
switch (info->level) {
|
||||
case TLOG_DEBUG:
|
||||
color = "\033[0;90m";
|
||||
break;
|
||||
case TLOG_NOTICE:
|
||||
color = "\033[0;97m";
|
||||
break;
|
||||
case TLOG_WARN:
|
||||
color = "\033[0;33m";
|
||||
break;
|
||||
case TLOG_ERROR:
|
||||
color = "\033[0;31m";
|
||||
break;
|
||||
case TLOG_FATAL:
|
||||
color = "\033[31;1m";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (color != NULL) {
|
||||
fprintf(stdout, "%s%.*s\033[0m\n", color, bufflen - 2, buff);
|
||||
} else {
|
||||
fprintf(stdout, "%s", buff);
|
||||
}
|
||||
} else {
|
||||
/* output log to screen */
|
||||
unused = write(STDOUT_FILENO, buff, bufflen);
|
||||
}
|
||||
|
||||
return bufflen;
|
||||
}
|
||||
|
||||
static int _tlog_write_ext(struct tlog_log *log, struct tlog_loginfo *info, const char *buff, int bufflen)
|
||||
static int _tlog_write(struct tlog_log *log, const char *buff, int bufflen)
|
||||
{
|
||||
int len;
|
||||
int unused __attribute__((unused));
|
||||
@@ -1215,7 +1161,7 @@ static int _tlog_write_ext(struct tlog_log *log, struct tlog_loginfo *info, cons
|
||||
|
||||
/* output log to screen */
|
||||
if (log->logscreen) {
|
||||
_tlog_write_screen(log, info, buff, bufflen);
|
||||
unused = write(STDOUT_FILENO, buff, bufflen);
|
||||
}
|
||||
|
||||
if (log->logcount <= 0) {
|
||||
@@ -1299,11 +1245,6 @@ static int _tlog_write_ext(struct tlog_log *log, struct tlog_loginfo *info, cons
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline int _tlog_write(struct tlog_log *log, const char *buff, int bufflen)
|
||||
{
|
||||
return _tlog_write_ext(log, NULL, buff, bufflen);
|
||||
}
|
||||
|
||||
int tlog_write(struct tlog_log *log, const char *buff, int bufflen)
|
||||
{
|
||||
return _tlog_write(log, buff, bufflen);
|
||||
@@ -1537,7 +1478,7 @@ static int _tlog_root_write_log(struct tlog_log *log, const char *buff, int buff
|
||||
if (tlog.output_func == NULL) {
|
||||
if (log->segment_log) {
|
||||
head = (struct tlog_segment_log_head *)buff;
|
||||
return _tlog_write_ext(log, &head->info, head->data, head->len);
|
||||
return _tlog_write(log, head->data, head->len);
|
||||
}
|
||||
return _tlog_write(log, buff, bufflen);
|
||||
}
|
||||
@@ -1679,11 +1620,6 @@ void tlog_set_early_printf(int enable)
|
||||
tlog_disable_early_print = (enable == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
void tlog_reg_early_printf_callback(tlog_early_print_func callback)
|
||||
{
|
||||
tlog_early_print = callback;
|
||||
}
|
||||
|
||||
const char *tlog_get_level_string(tlog_level level)
|
||||
{
|
||||
if (level >= TLOG_END) {
|
||||
@@ -1809,7 +1745,7 @@ static void _tlog_get_gzip_cmd_path(void)
|
||||
if (access(gzip_cmd_path, X_OK) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
snprintf(tlog.gzip_cmd, sizeof(tlog.gzip_cmd), "%s", gzip_cmd_path);
|
||||
break;
|
||||
}
|
||||
@@ -1850,7 +1786,6 @@ tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int bu
|
||||
log->block = ((flag & TLOG_NONBLOCK) == 0) ? 1 : 0;
|
||||
log->nocompress = ((flag & TLOG_NOCOMPRESS) == 0) ? 0 : 1;
|
||||
log->logscreen = ((flag & TLOG_SCREEN) == 0) ? 0 : 1;
|
||||
log->logscreen_color = ((flag & TLOG_SCREEN_COLOR) == 0) ? 0 : 1;
|
||||
log->multi_log = ((flag & TLOG_MULTI_WRITE) == 0) ? 0 : 1;
|
||||
log->segment_log = ((flag & TLOG_SEGMENT) == 0) ? 0 : 1;
|
||||
log->max_line_size = TLOG_MAX_LINE_LEN;
|
||||
@@ -1862,11 +1797,6 @@ tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int bu
|
||||
log->nocompress = 1;
|
||||
}
|
||||
|
||||
if (log->logscreen_color == 1) {
|
||||
log->logscreen = 1;
|
||||
log->segment_log = 1;
|
||||
}
|
||||
|
||||
tlog_rename_logfile(log, logfile);
|
||||
if (log->nocompress) {
|
||||
strncpy(log->suffix, TLOG_SUFFIX_LOG, sizeof(log->suffix));
|
||||
@@ -2040,7 +1970,6 @@ errout:
|
||||
pthread_mutex_destroy(&tlog.lock);
|
||||
tlog.run = 0;
|
||||
tlog.root = NULL;
|
||||
tlog_format = NULL;
|
||||
|
||||
_tlog_close(log, 1);
|
||||
|
||||
@@ -2049,10 +1978,6 @@ errout:
|
||||
|
||||
void tlog_exit(void)
|
||||
{
|
||||
if (tlog_format == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tlog.tid) {
|
||||
void *ret = NULL;
|
||||
tlog.run = 0;
|
||||
|
||||
@@ -66,9 +66,6 @@ struct tlog_time {
|
||||
/* enable support fork process */
|
||||
#define TLOG_SUPPORT_FORK (1 << 5)
|
||||
|
||||
/* enable output to screen with color */
|
||||
#define TLOG_SCREEN_COLOR (1 << 6)
|
||||
|
||||
struct tlog_loginfo {
|
||||
tlog_level level;
|
||||
const char *file;
|
||||
@@ -114,10 +111,6 @@ extern void tlog_setlogscreen(int enable);
|
||||
/* enable early log to screen */
|
||||
extern void tlog_set_early_printf(int enable);
|
||||
|
||||
/* set early log callback */
|
||||
typedef void (*tlog_early_print_func)(struct tlog_loginfo *loginfo, const char *format, va_list ap);
|
||||
extern void tlog_reg_early_printf_callback(tlog_early_print_func callback);
|
||||
|
||||
/* Get log level in string */
|
||||
extern const char *tlog_get_level_string(tlog_level level);
|
||||
|
||||
@@ -304,4 +297,4 @@ private:
|
||||
#define tlog_error(...) tlog(TLOG_ERROR, ##__VA_ARGS__)
|
||||
#define tlog_fatal(...) tlog(TLOG_FATAL, ##__VA_ARGS__)
|
||||
#endif
|
||||
#endif // !TLOG_H
|
||||
#endif // !TLOG_H
|
||||
|
||||
88
src/util.c
88
src/util.c
@@ -188,8 +188,7 @@ int generate_random_addr(unsigned char *addr, int addr_len, int mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generate_addr_map(const unsigned char *addr_from, const unsigned char *addr_to, unsigned char *addr_out,
|
||||
int addr_len, int mask)
|
||||
int generate_addr_map(const unsigned char *addr_from, const unsigned char *addr_to, unsigned char *addr_out, int addr_len, int mask)
|
||||
{
|
||||
if ((mask / 8) >= addr_len) {
|
||||
if (mask % 8 != 0) {
|
||||
@@ -1065,10 +1064,6 @@ void SSL_CRYPTO_thread_setup(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (lock_cs != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
|
||||
lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
|
||||
if (!lock_cs || !lock_count) {
|
||||
@@ -1098,18 +1093,12 @@ void SSL_CRYPTO_thread_cleanup(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (lock_cs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for (i = 0; i < CRYPTO_num_locks(); i++) {
|
||||
pthread_mutex_destroy(&(lock_cs[i]));
|
||||
}
|
||||
OPENSSL_free(lock_cs);
|
||||
OPENSSL_free(lock_count);
|
||||
lock_cs = NULL;
|
||||
lock_count = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1386,8 +1375,8 @@ int set_sock_keepalive(int fd, int keepidle, int keepinterval, int keepcnt)
|
||||
}
|
||||
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepinterval, sizeof(keepinterval));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepinterval, sizeof(keepinterval));
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepcnt, sizeof(keepcnt));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1487,7 +1476,7 @@ void bug_ext(const char *file, int line, const char *func, const char *errfmt, .
|
||||
|
||||
int write_file(const char *filename, void *data, int data_len)
|
||||
{
|
||||
int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
|
||||
int fd = open(filename, O_WRONLY | O_CREAT, 0644);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1535,9 +1524,9 @@ int dns_packet_save(const char *dir, const char *type, const char *from, const v
|
||||
|
||||
snprintf(time_s, sizeof(time_s) - 1, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d", ptm->tm_year + 1900, ptm->tm_mon + 1,
|
||||
ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (int)(tm_val.tv_usec / 1000));
|
||||
snprintf(filename, sizeof(filename) - 1, "%s/%s-%.4d%.2d%.2d-%.2d%.2d%.2d%.3d.packet", dir, type,
|
||||
snprintf(filename, sizeof(filename) - 1, "%s/%s-%.4d%.2d%.2d-%.2d%.2d%.2d%.1d.packet", dir, type,
|
||||
ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec,
|
||||
(int)(tm_val.tv_usec / 1000));
|
||||
(int)(tm_val.tv_usec / 100000));
|
||||
|
||||
data = malloc(PACKET_BUF_SIZE);
|
||||
if (data == NULL) {
|
||||
@@ -1632,23 +1621,6 @@ errout:
|
||||
return;
|
||||
}
|
||||
|
||||
void daemon_close_stdfds(void)
|
||||
{
|
||||
int fd_null = open("/dev/null", O_RDWR);
|
||||
if (fd_null < 0) {
|
||||
fprintf(stderr, "open /dev/null failed, %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
dup2(fd_null, STDIN_FILENO);
|
||||
dup2(fd_null, STDOUT_FILENO);
|
||||
dup2(fd_null, STDERR_FILENO);
|
||||
|
||||
if (fd_null > 2) {
|
||||
close(fd_null);
|
||||
}
|
||||
}
|
||||
|
||||
int daemon_kickoff(int status, int no_close)
|
||||
{
|
||||
struct daemon_msg msg;
|
||||
@@ -1667,7 +1639,19 @@ int daemon_kickoff(int status, int no_close)
|
||||
}
|
||||
|
||||
if (no_close == 0) {
|
||||
daemon_close_stdfds();
|
||||
int fd_null = open("/dev/null", O_RDWR);
|
||||
if (fd_null < 0) {
|
||||
fprintf(stderr, "open /dev/null failed, %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dup2(fd_null, STDIN_FILENO);
|
||||
dup2(fd_null, STDOUT_FILENO);
|
||||
dup2(fd_null, STDERR_FILENO);
|
||||
|
||||
if (fd_null > 2) {
|
||||
close(fd_null);
|
||||
}
|
||||
}
|
||||
|
||||
close(daemon_fd);
|
||||
@@ -1703,7 +1687,7 @@ int daemon_keepalive(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
daemon_ret daemon_run(int *wstatus)
|
||||
int daemon_run(void)
|
||||
{
|
||||
pid_t pid = 0;
|
||||
int fds[2] = {0};
|
||||
@@ -1753,16 +1737,11 @@ daemon_ret daemon_run(int *wstatus)
|
||||
pid = msg.value;
|
||||
continue;
|
||||
} else if (msg.type == DAEMON_MSG_KICKOFF) {
|
||||
if (wstatus != NULL) {
|
||||
*wstatus = msg.value;
|
||||
}
|
||||
return DAEMON_RET_PARENT_OK;
|
||||
return msg.value;
|
||||
} else {
|
||||
goto errout;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return DAEMON_RET_ERR;
|
||||
}
|
||||
|
||||
setsid();
|
||||
@@ -1787,13 +1766,10 @@ daemon_ret daemon_run(int *wstatus)
|
||||
close(fds[0]);
|
||||
|
||||
daemon_fd = fds[1];
|
||||
return DAEMON_RET_CHILD_OK;
|
||||
return -2;
|
||||
errout:
|
||||
kill(pid, SIGKILL);
|
||||
if (wstatus != NULL) {
|
||||
*wstatus = -1;
|
||||
}
|
||||
return DAEMON_RET_ERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -1913,24 +1889,6 @@ static int _dns_debug_display(struct dns_packet *packet)
|
||||
inet_ntop(AF_INET6, addr, req_host, sizeof(req_host));
|
||||
printf("domain: %s AAAA: %s TTL:%d\n", name, req_host, ttl);
|
||||
} break;
|
||||
case DNS_T_SRV: {
|
||||
unsigned short priority = 0;
|
||||
unsigned short weight = 0;
|
||||
unsigned short port = 0;
|
||||
int ret = 0;
|
||||
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
char target[DNS_MAX_CNAME_LEN];
|
||||
|
||||
ret = dns_get_SRV(rrs, name, DNS_MAX_CNAME_LEN, &ttl, &priority, &weight, &port, target, DNS_MAX_CNAME_LEN);
|
||||
if (ret < 0) {
|
||||
tlog(TLOG_DEBUG, "decode SRV failed, %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("domain: %s SRV: %s TTL: %d priority: %d weight: %d port: %d\n", name, target, ttl, priority,
|
||||
weight, port);
|
||||
} break;
|
||||
case DNS_T_HTTPS: {
|
||||
char name[DNS_MAX_CNAME_LEN] = {0};
|
||||
char target[DNS_MAX_CNAME_LEN] = {0};
|
||||
|
||||
11
src/util.h
11
src/util.h
@@ -147,21 +147,12 @@ void print_stack(void);
|
||||
|
||||
void close_all_fd(int keepfd);
|
||||
|
||||
typedef enum daemon_ret {
|
||||
DAEMON_RET_OK = 0,
|
||||
DAEMON_RET_ERR = -1,
|
||||
DAEMON_RET_CHILD_OK = -2,
|
||||
DAEMON_RET_PARENT_OK = -3,
|
||||
} daemon_ret;
|
||||
|
||||
daemon_ret daemon_run(int *wstatus);
|
||||
int daemon_run(void);
|
||||
|
||||
int daemon_kickoff(int status, int no_close);
|
||||
|
||||
int daemon_keepalive(void);
|
||||
|
||||
void daemon_close_stdfds(void);
|
||||
|
||||
int write_file(const char *filename, void *data, int data_len);
|
||||
|
||||
int dns_packet_save(const char *dir, const char *type, const char *from, const void *packet, int packet_len);
|
||||
|
||||
@@ -23,7 +23,7 @@ CXXFLAGS += -g
|
||||
CXXFLAGS += -DTEST
|
||||
CXXFLAGS += -I./ -I../src -I../src/include
|
||||
|
||||
SMARTDNS_OBJS = lib/rbtree.o lib/art.o lib/bitops.o lib/radix.o lib/conf.o lib/nftset.o lib/timer_wheel.o lib/idna.o
|
||||
SMARTDNS_OBJS = lib/rbtree.o lib/art.o lib/bitops.o lib/radix.o lib/conf.o lib/nftset.o lib/timer_wheel.o
|
||||
SMARTDNS_OBJS += smartdns.o fast_ping.o dns_client.o dns_server.o dns.o util.o tlog.o dns_conf.o dns_cache.o http_parse.o proxy.o timer.o
|
||||
OBJS = $(addprefix ../src/, $(SMARTDNS_OBJS))
|
||||
|
||||
|
||||
@@ -56,36 +56,6 @@ cache-persist no)""");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
}
|
||||
|
||||
TEST(Bind, https)
|
||||
{
|
||||
Defer
|
||||
{
|
||||
unlink("/tmp/smartdns-cert.pem");
|
||||
unlink("/tmp/smartdns-key.pem");
|
||||
};
|
||||
|
||||
smartdns::Server server_wrap;
|
||||
smartdns::Server server;
|
||||
|
||||
server.Start(R"""(bind [::]:61053
|
||||
server https://127.0.0.1:60053 -no-check-certificate
|
||||
log-num 0
|
||||
log-console yes
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
server_wrap.Start(R"""(bind-https [::]:60053
|
||||
address /example.com/1.2.3.4
|
||||
log-num 0
|
||||
log-console yes
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("example.com", 61053));
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
}
|
||||
|
||||
TEST(Bind, udp_tcp)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
@@ -282,71 +252,3 @@ cache-persist no)""");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
}
|
||||
|
||||
|
||||
TEST(Bind, group)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::MockServer server_upstream1;
|
||||
smartdns::MockServer server_upstream2;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "9.10.11.12", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server_upstream1.Start("udp://0.0.0.0:62053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server_upstream2.Start("udp://0.0.0.0:63053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
bind [::]:60153 -group g1
|
||||
bind [::]:60253 -group g2
|
||||
server 127.0.0.1:61053
|
||||
server 127.0.0.1:62053 -group g1 -exclude-default-group
|
||||
server 127.0.0.1:63053 -group g2 -exclude-default-group
|
||||
log-num 0
|
||||
log-console yes
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "9.10.11.12");
|
||||
|
||||
ASSERT_TRUE(client.Query("a.com", 60153));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
|
||||
ASSERT_TRUE(client.Query("a.com", 60253));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "5.6.7.8");
|
||||
}
|
||||
|
||||
@@ -191,89 +191,6 @@ cache-persist no)""");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
}
|
||||
|
||||
TEST_F(Cache, prefetch)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::MockServer server_upstream1;
|
||||
smartdns::MockServer server_upstream2;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "9.10.11.12", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server_upstream1.Start("udp://0.0.0.0:62053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server_upstream2.Start("udp://0.0.0.0:63053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "5.6.7.8", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 100);
|
||||
server.MockPing(PING_TYPE_ICMP, "5.6.7.8", 60, 110);
|
||||
server.MockPing(PING_TYPE_ICMP, "9.10.11.12", 60, 110);
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
bind [::]:60153 -group g1
|
||||
server 127.0.0.1:61053
|
||||
server 127.0.0.1:62053 -group g1 -exclude-default-group
|
||||
server 127.0.0.1:63053 -group g2
|
||||
log-num 0
|
||||
prefetch-domain yes
|
||||
rr-ttl-max 2
|
||||
serve-expired no
|
||||
log-console yes
|
||||
log-level debug
|
||||
srv-record-selection no
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
|
||||
ASSERT_TRUE(client.Query("a.com", 60153));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
|
||||
sleep(1);
|
||||
|
||||
ASSERT_TRUE(client.Query("a.com", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 2);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
|
||||
sleep(1);
|
||||
|
||||
ASSERT_TRUE(client.Query("a.com", 60153));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
}
|
||||
|
||||
TEST_F(Cache, nocache)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
|
||||
266
test/cases/test-https.cc
Normal file
266
test/cases/test-https.cc
Normal file
@@ -0,0 +1,266 @@
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||
*
|
||||
* smartdns is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* smartdns is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include "dns.h"
|
||||
#include "include/utils.h"
|
||||
#include "server.h"
|
||||
#include "util.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <fstream>
|
||||
|
||||
class HTTPS : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
};
|
||||
|
||||
TEST_F(HTTPS, ipv4_speed_prefer)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_HTTPS) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = request->response_packet;
|
||||
struct dns_rr_nested svcparam_buffer;
|
||||
|
||||
dns_add_HTTPS_start(&svcparam_buffer, packet, DNS_RRS_AN, request->domain.c_str(), 3, 1, "b.com");
|
||||
const char alph[] = "\x02h2\x05h3-19";
|
||||
int alph_len = sizeof(alph) - 1;
|
||||
dns_HTTPS_add_alpn(&svcparam_buffer, alph, alph_len);
|
||||
dns_HTTPS_add_port(&svcparam_buffer, 443);
|
||||
unsigned char add_v4[] = {1, 2, 3, 4};
|
||||
unsigned char *addr[1] = {add_v4};
|
||||
dns_HTTPS_add_ipv4hint(&svcparam_buffer, addr, 1);
|
||||
unsigned char ech[] = {0x00, 0x45, 0xfe, 0x0d, 0x00};
|
||||
dns_HTTPS_add_ech(&svcparam_buffer, (void *)ech, sizeof(ech));
|
||||
unsigned char add_v6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
||||
addr[0] = add_v6;
|
||||
dns_HTTPS_add_ipv6hint(&svcparam_buffer, addr, 1);
|
||||
dns_add_HTTPS_end(&svcparam_buffer);
|
||||
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 10);
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-console yes
|
||||
dualstack-ip-selection no
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "HTTPS");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1 b.com. alpn=\"h2,h3-19\" port=443 ipv4hint=1.2.3.4 ech=AEX+DQA=");
|
||||
}
|
||||
|
||||
TEST_F(HTTPS, ipv6_speed_prefer)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_HTTPS) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = request->response_packet;
|
||||
struct dns_rr_nested svcparam_buffer;
|
||||
|
||||
dns_add_HTTPS_start(&svcparam_buffer, packet, DNS_RRS_AN, request->domain.c_str(), 3, 1, "b.com");
|
||||
const char alph[] = "\x02h2\x05h3-19";
|
||||
int alph_len = sizeof(alph) - 1;
|
||||
dns_HTTPS_add_alpn(&svcparam_buffer, alph, alph_len);
|
||||
dns_HTTPS_add_port(&svcparam_buffer, 443);
|
||||
unsigned char add_v4[] = {1, 2, 3, 4};
|
||||
unsigned char *addr[1] = {add_v4};
|
||||
dns_HTTPS_add_ipv4hint(&svcparam_buffer, addr, 1);
|
||||
unsigned char ech[] = {0x00, 0x45, 0xfe, 0x0d, 0x00};
|
||||
dns_HTTPS_add_ech(&svcparam_buffer, (void *)ech, sizeof(ech));
|
||||
unsigned char add_v6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
||||
addr[0] = add_v6;
|
||||
dns_HTTPS_add_ipv6hint(&svcparam_buffer, addr, 1);
|
||||
dns_add_HTTPS_end(&svcparam_buffer);
|
||||
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.MockPing(PING_TYPE_ICMP, "102:304:506:708:90a:b0c:d0e:f10", 60, 10);
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-console yes
|
||||
dualstack-ip-selection no
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "HTTPS");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(),
|
||||
"1 b.com. alpn=\"h2,h3-19\" port=443 ech=AEX+DQA= ipv6hint=102:304:506:708:90a:b0c:d0e:f10");
|
||||
}
|
||||
|
||||
TEST_F(HTTPS, ipv4_SOA)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_HTTPS) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = request->response_packet;
|
||||
struct dns_rr_nested svcparam_buffer;
|
||||
|
||||
dns_add_HTTPS_start(&svcparam_buffer, packet, DNS_RRS_AN, request->domain.c_str(), 3, 1, "a.com");
|
||||
const char alph[] = "\x02h2\x05h3-19";
|
||||
int alph_len = sizeof(alph) - 1;
|
||||
dns_HTTPS_add_alpn(&svcparam_buffer, alph, alph_len);
|
||||
dns_HTTPS_add_port(&svcparam_buffer, 443);
|
||||
unsigned char add_v4[] = {1, 2, 3, 4};
|
||||
unsigned char *addr[1] = {add_v4};
|
||||
dns_HTTPS_add_ipv4hint(&svcparam_buffer, addr, 1);
|
||||
unsigned char ech[] = {0x00, 0x45, 0xfe, 0x0d, 0x00};
|
||||
dns_HTTPS_add_ech(&svcparam_buffer, (void *)ech, sizeof(ech));
|
||||
unsigned char add_v6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
||||
addr[0] = add_v6;
|
||||
dns_HTTPS_add_ipv6hint(&svcparam_buffer, addr, 1);
|
||||
dns_add_HTTPS_end(&svcparam_buffer);
|
||||
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-console yes
|
||||
dualstack-ip-selection no
|
||||
address /a.com/#4
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 61053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
auto result_check = client.GetAnswer()[0].GetData();
|
||||
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "HTTPS");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(),
|
||||
"1 a.com. alpn=\"h2,h3-19\" port=443 ech=AEX+DQA= ipv6hint=102:304:506:708:90a:b0c:d0e:f10");
|
||||
}
|
||||
|
||||
TEST_F(HTTPS, ipv6_SOA)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_HTTPS) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = request->response_packet;
|
||||
struct dns_rr_nested svcparam_buffer;
|
||||
|
||||
dns_add_HTTPS_start(&svcparam_buffer, packet, DNS_RRS_AN, request->domain.c_str(), 3, 1, "a.com");
|
||||
const char alph[] = "\x02h2\x05h3-19";
|
||||
int alph_len = sizeof(alph) - 1;
|
||||
dns_HTTPS_add_alpn(&svcparam_buffer, alph, alph_len);
|
||||
dns_HTTPS_add_port(&svcparam_buffer, 443);
|
||||
unsigned char add_v4[] = {1, 2, 3, 4};
|
||||
unsigned char *addr[1] = {add_v4};
|
||||
dns_HTTPS_add_ipv4hint(&svcparam_buffer, addr, 1);
|
||||
unsigned char ech[] = {0x00, 0x45, 0xfe, 0x0d, 0x00};
|
||||
dns_HTTPS_add_ech(&svcparam_buffer, (void *)ech, sizeof(ech));
|
||||
unsigned char add_v6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
||||
addr[0] = add_v6;
|
||||
dns_HTTPS_add_ipv6hint(&svcparam_buffer, addr, 1);
|
||||
dns_add_HTTPS_end(&svcparam_buffer);
|
||||
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-console yes
|
||||
dualstack-ip-selection no
|
||||
address /a.com/#6
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 61053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
auto result_check = client.GetAnswer()[0].GetData();
|
||||
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 3);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "HTTPS");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1 a.com. alpn=\"h2,h3-19\" port=443 ipv4hint=1.2.3.4 ech=AEX+DQA=");
|
||||
}
|
||||
|
||||
TEST_F(HTTPS, SOA)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-console yes
|
||||
dualstack-ip-selection no
|
||||
address /a.com/#6
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAuthorityNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NXDOMAIN");
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 60);
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||
*
|
||||
* smartdns is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* smartdns is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include "dns.h"
|
||||
#include "include/utils.h"
|
||||
#include "server.h"
|
||||
#include "util.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <fstream>
|
||||
|
||||
class IDNA : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
};
|
||||
|
||||
TEST_F(IDNA, match)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype == DNS_T_A) {
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 700);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
} else if (request->qtype == DNS_T_AAAA) {
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "64:ff9b::102:304", 700);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
}
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-num 0
|
||||
log-console yes
|
||||
log-level debug
|
||||
speed-check-mode none
|
||||
address /中国.com/10.10.10.10
|
||||
address /中国.com/64:ff9b::1010:1010
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("xn--fiqs8s.com A", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "xn--fiqs8s.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "A");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "10.10.10.10");
|
||||
|
||||
ASSERT_TRUE(client.Query("xn--fiqs8s.com AAAA", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "xn--fiqs8s.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "AAAA");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "64:ff9b::1010:1010");
|
||||
}
|
||||
@@ -73,48 +73,6 @@ cache-persist no)""");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "4.5.6.7");
|
||||
}
|
||||
|
||||
TEST_F(IPRule, white_list_not_in)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::MockServer server_upstream2;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server_upstream2.Start("udp://0.0.0.0:62053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "9.10.11.12", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
/* this ip will be discard, but is reachable */
|
||||
server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 10);
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server udp://127.0.0.1:61053 -whitelist-ip
|
||||
server udp://127.0.0.1:62053 -whitelist-ip
|
||||
whitelist-ip 4.5.6.7/24
|
||||
log-num 0
|
||||
log-console yes
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 0);
|
||||
EXPECT_EQ(client.GetStatus(), "SERVFAIL");
|
||||
}
|
||||
|
||||
TEST_F(IPRule, black_list)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
@@ -252,72 +210,3 @@ cache-persist no)""");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "7.8.9.10");
|
||||
}
|
||||
|
||||
TEST_F(IPRule, ip_alias_ip_set)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::MockServer server_upstream2;
|
||||
smartdns::Server server;
|
||||
std::string file = "/tmp/smartdns_test_ip_set.list" + smartdns::GenerateRandomString(5);
|
||||
std::string file_ip = "/tmp/smartdns_test_ip_set_ip.list" + smartdns::GenerateRandomString(5);
|
||||
std::ofstream ofs(file);
|
||||
std::ofstream ofs_ip(file_ip);
|
||||
ASSERT_TRUE(ofs.is_open());
|
||||
ASSERT_TRUE(ofs_ip.is_open());
|
||||
Defer
|
||||
{
|
||||
ofs.close();
|
||||
unlink(file.c_str());
|
||||
ofs_ip.close();
|
||||
unlink(file_ip.c_str());
|
||||
};
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_A) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 611);
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "4.5.6.7", 611);
|
||||
smartdns::MockServer::AddIP(request, request->domain.c_str(), "7.8.9.10", 611);
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.MockPing(PING_TYPE_ICMP, "1.2.3.4", 60, 10);
|
||||
server.MockPing(PING_TYPE_ICMP, "4.5.6.7", 60, 90);
|
||||
server.MockPing(PING_TYPE_ICMP, "7.8.9.10", 60, 40);
|
||||
|
||||
std::string ipset_list = R"""(
|
||||
1.2.3.0/24
|
||||
4.5.6.0/24
|
||||
7.8.9.0/24
|
||||
)""";
|
||||
ofs.write(ipset_list.c_str(), ipset_list.length());
|
||||
ofs.flush();
|
||||
|
||||
std::string ipset_list_ip = R"""(
|
||||
1.1.1.1
|
||||
)""";
|
||||
ofs_ip.write(ipset_list_ip.c_str(), ipset_list_ip.length());
|
||||
ofs_ip.flush();
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server udp://127.0.0.1:61053 -blacklist-ip
|
||||
ip-set -name ip-list -file )""" +
|
||||
file + R"""(
|
||||
ip-set -name ip-list-ip -file )""" +
|
||||
file_ip + R"""(
|
||||
ip-alias ip-set:ip-list ip-set:ip-list-ip
|
||||
log-num 0
|
||||
speed-check-mode none
|
||||
log-console yes
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.1.1.1");
|
||||
}
|
||||
|
||||
@@ -255,3 +255,55 @@ cache-persist no)""");
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 30);
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_F(QtypeSOA, HTTPS_SOA)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
std::map<int, int> qid_map;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_HTTPS) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = request->response_packet;
|
||||
struct dns_rr_nested svcparam_buffer;
|
||||
|
||||
dns_add_HTTPS_start(&svcparam_buffer, packet, DNS_RRS_AN, request->domain.c_str(), 3, 1, "a.com");
|
||||
const char alph[] = "\x02h2\x05h3-19";
|
||||
int alph_len = sizeof(alph) - 1;
|
||||
dns_HTTPS_add_alpn(&svcparam_buffer, alph, alph_len);
|
||||
dns_HTTPS_add_port(&svcparam_buffer, 443);
|
||||
unsigned char add_v4[] = {1, 2, 3, 4};
|
||||
unsigned char *addr[1] = {add_v4};
|
||||
dns_HTTPS_add_ipv4hint(&svcparam_buffer, addr, 1);
|
||||
unsigned char ech[] = {0x00, 0x45, 0xfe, 0x0d, 0x00};
|
||||
dns_HTTPS_add_ech(&svcparam_buffer, (void *)ech, sizeof(ech));
|
||||
unsigned char add_v6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
||||
addr[0] = add_v6;
|
||||
dns_HTTPS_add_ipv6hint(&svcparam_buffer, addr, 1);
|
||||
dns_add_HTTPS_end(&svcparam_buffer);
|
||||
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-console yes
|
||||
dualstack-ip-selection no
|
||||
speed-check-mode none
|
||||
address /a.com/#
|
||||
log-level debug
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("a.com HTTPS", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAuthorityNum(), 1);
|
||||
EXPECT_EQ(client.GetStatus(), "NXDOMAIN");
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetTTL(), 30);
|
||||
EXPECT_EQ(client.GetAuthority()[0].GetType(), "SOA");
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ cache-persist no)""");
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 2);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_LT(client.GetQueryTime(), 40);
|
||||
EXPECT_LT(client.GetQueryTime(), 20);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "b.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||
|
||||
@@ -107,7 +107,7 @@ cache-persist no)""");
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 2);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_LT(client.GetQueryTime(), 40);
|
||||
EXPECT_LT(client.GetQueryTime(), 20);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "a.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1.2.3.4");
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||
*
|
||||
* smartdns is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* smartdns is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include "dns.h"
|
||||
#include "include/utils.h"
|
||||
#include "server.h"
|
||||
#include "util.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <fstream>
|
||||
|
||||
class SRV : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
};
|
||||
|
||||
TEST_F(SRV, query)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_SRV) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = request->response_packet;
|
||||
dns_add_SRV(packet, DNS_RRS_AN, request->domain.c_str(), 603, 1, 1, 443, "www.example.com");
|
||||
dns_add_SRV(packet, DNS_RRS_AN, request->domain.c_str(), 603, 1, 1, 443, "www1.example.com");
|
||||
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-num 0
|
||||
log-console yes
|
||||
log-level debug
|
||||
speed-check-mode none
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("_ldap._tcp.local.com SRV", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 2);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "_ldap._tcp.local.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 603);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "SRV");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1 1 443 www.example.com.");
|
||||
}
|
||||
|
||||
TEST_F(SRV, match)
|
||||
{
|
||||
smartdns::MockServer server_upstream;
|
||||
smartdns::Server server;
|
||||
|
||||
server_upstream.Start("udp://0.0.0.0:61053", [&](struct smartdns::ServerRequestContext *request) {
|
||||
if (request->qtype != DNS_T_SRV) {
|
||||
return smartdns::SERVER_REQUEST_SOA;
|
||||
}
|
||||
|
||||
struct dns_packet *packet = request->response_packet;
|
||||
dns_add_SRV(packet, DNS_RRS_AN, request->domain.c_str(), 603, 1, 1, 443, "www.example.com");
|
||||
dns_add_SRV(packet, DNS_RRS_AN, request->domain.c_str(), 603, 1, 1, 443, "www1.example.com");
|
||||
|
||||
return smartdns::SERVER_REQUEST_OK;
|
||||
});
|
||||
|
||||
server.Start(R"""(bind [::]:60053
|
||||
server 127.0.0.1:61053
|
||||
log-num 0
|
||||
log-console yes
|
||||
log-level debug
|
||||
srv-record /_ldap._tcp.local.com/www.a.com,443,1,1
|
||||
srv-record /_ldap._tcp.local.com/www1.a.com,443,1,1
|
||||
srv-record /_ldap._tcp.local.com/www2.a.com,443,1,1
|
||||
speed-check-mode none
|
||||
cache-persist no)""");
|
||||
smartdns::Client client;
|
||||
ASSERT_TRUE(client.Query("_ldap._tcp.local.com SRV", 60053));
|
||||
std::cout << client.GetResult() << std::endl;
|
||||
ASSERT_EQ(client.GetAnswerNum(), 3);
|
||||
EXPECT_EQ(client.GetStatus(), "NOERROR");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetName(), "_ldap._tcp.local.com");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetTTL(), 600);
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetType(), "SRV");
|
||||
EXPECT_EQ(client.GetAnswer()[0].GetData(), "1 1 443 www.a.com.");
|
||||
}
|
||||
@@ -55,7 +55,7 @@ TEST_F(SubNet, pass_subnet)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ TEST_F(SubNet, conf)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ TEST_F(SubNet, conf_v6)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -269,7 +269,7 @@ TEST_F(SubNet, v4_server_subnet_txt)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ TEST_F(SubNet, v6_default_subnet_txt)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -410,7 +410,7 @@ TEST_F(SubNet, per_server)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -442,7 +442,7 @@ TEST_F(SubNet, per_server)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -479,7 +479,7 @@ TEST_F(SubNet, per_server)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -524,7 +524,7 @@ TEST_F(SubNet, per_server)
|
||||
|
||||
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(request->packet, rrs)) {
|
||||
memset(&ecs, 0, sizeof(ecs));
|
||||
ret = dns_get_OPT_ECS(rrs, &ecs);
|
||||
ret = dns_get_OPT_ECS(rrs, NULL, NULL, &ecs);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user