1.1.1修复
This commit is contained in:
320
dns/server.go
320
dns/server.go
@@ -59,6 +59,8 @@ type QueryLog struct {
|
||||
FromCache bool // 是否来自缓存
|
||||
DNSSEC bool // 是否使用了DNSSEC
|
||||
EDNS bool // 是否使用了EDNS
|
||||
DNSServer string // 使用的DNS服务器
|
||||
DNSSECServer string // 使用的DNSSEC专用服务器
|
||||
}
|
||||
|
||||
// StatsData 用于持久化的统计数据结构
|
||||
@@ -230,14 +232,14 @@ func (s *Server) Start() error {
|
||||
s.startTime = time.Now()
|
||||
|
||||
s.server = &dns.Server{
|
||||
Addr: fmt.Sprintf(":%d", s.config.Port),
|
||||
Addr: fmt.Sprintf("0.0.0.0:%d", s.config.Port),
|
||||
Net: "udp",
|
||||
Handler: dns.HandlerFunc(s.handleDNSRequest),
|
||||
}
|
||||
|
||||
// 保存TCP服务器实例,以便在Stop方法中关闭
|
||||
s.tcpServer = &dns.Server{
|
||||
Addr: fmt.Sprintf(":%d", s.config.Port),
|
||||
Addr: fmt.Sprintf("0.0.0.0:%d", s.config.Port),
|
||||
Net: "tcp",
|
||||
Handler: dns.HandlerFunc(s.handleDNSRequest),
|
||||
}
|
||||
@@ -368,7 +370,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
})
|
||||
|
||||
// 添加查询日志
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "error", "", "", false, false, true)
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "error", "", "", false, false, true, "", "")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -385,7 +387,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
})
|
||||
|
||||
// 添加查询日志
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", false, false, true)
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", false, false, true, "缓存", "无")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -407,7 +409,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
})
|
||||
|
||||
// 添加查询日志
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "blocked", blockRule, blockType, false, false, true)
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "blocked", blockRule, blockType, false, false, true, "无", "无")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -480,7 +482,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
}
|
||||
|
||||
// 添加查询日志 - 标记为缓存
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", true, cachedDNSSEC, true)
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", true, cachedDNSSEC, true, "缓存", "无")
|
||||
logger.Debug("从缓存返回DNS响应", "domain", domain, "type", queryType, "dnssec", cachedDNSSEC)
|
||||
return
|
||||
}
|
||||
@@ -489,10 +491,12 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
var response *dns.Msg
|
||||
var rtt time.Duration
|
||||
var queryAttempts []string
|
||||
var dnsServer string
|
||||
var dnssecServer string
|
||||
|
||||
// 1. 首先尝试直接查询原始域名
|
||||
queryAttempts = append(queryAttempts, domain)
|
||||
response, rtt = s.forwardDNSRequestWithCache(r, domain)
|
||||
response, rtt, dnsServer, dnssecServer = s.forwardDNSRequestWithCache(r, domain)
|
||||
|
||||
// 2. 如果直接查询失败且配置了prefixDomain,尝试添加前缀
|
||||
if (response == nil || response.Rcode != dns.RcodeSuccess) && len(s.config.PrefixDomain) > 0 {
|
||||
@@ -517,8 +521,8 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
Qclass: originalQuestion.Qclass,
|
||||
}
|
||||
|
||||
// 转发请求
|
||||
response, rtt = s.forwardDNSRequestWithCache(newReq, fullDomain)
|
||||
// 查询带有前缀的域名
|
||||
response, rtt, dnsServer, dnssecServer = s.forwardDNSRequestWithCache(newReq, fullDomain)
|
||||
if response != nil && response.Rcode == dns.RcodeSuccess {
|
||||
logger.Debug("使用prefixDomain查询成功", "fullDomain", fullDomain, "originalDomain", domain)
|
||||
break // 找到成功的响应,退出循环
|
||||
@@ -595,7 +599,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
}
|
||||
|
||||
// 添加查询日志 - 标记为实时
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", false, responseDNSSEC, true)
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", false, responseDNSSEC, true, dnsServer, dnssecServer)
|
||||
}
|
||||
|
||||
// handleHostsResponse 处理hosts文件匹配的响应
|
||||
@@ -708,7 +712,7 @@ type serverResponse struct {
|
||||
}
|
||||
|
||||
// forwardDNSRequestWithCache 转发DNS请求到上游服务器并返回响应
|
||||
func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg, time.Duration) {
|
||||
func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg, time.Duration, string, string) {
|
||||
// 始终支持EDNS
|
||||
var udpSize uint16 = 4096
|
||||
var doFlag bool = s.config.EnableDNSSEC
|
||||
@@ -746,9 +750,16 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 如果没有匹配的域名特定配置,使用默认的上游DNS服务器
|
||||
// 2. 如果没有匹配的域名特定配置
|
||||
if !domainMatched {
|
||||
selectedUpstreamDNS = s.config.UpstreamDNS
|
||||
// 如果启用了DNSSEC且有配置DNSSEC专用服务器,则使用DNSSEC专用服务器
|
||||
if s.config.EnableDNSSEC && len(s.config.DNSSECUpstreamDNS) > 0 {
|
||||
selectedUpstreamDNS = s.config.DNSSECUpstreamDNS
|
||||
logger.Debug("使用DNSSEC专用服务器", "servers", selectedUpstreamDNS)
|
||||
} else {
|
||||
// 否则使用默认的上游DNS服务器
|
||||
selectedUpstreamDNS = s.config.UpstreamDNS
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 首先尝试所有配置的上游DNS服务器
|
||||
@@ -759,6 +770,8 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
var backupResponse *dns.Msg
|
||||
var backupRtt time.Duration
|
||||
var hasBackup bool
|
||||
var usedDNSServer string
|
||||
var usedDNSSECServer string
|
||||
|
||||
// 根据查询模式处理请求
|
||||
switch s.config.QueryMode {
|
||||
@@ -832,21 +845,47 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
}
|
||||
}
|
||||
|
||||
// 如果响应成功,根据DNSSEC状态选择最佳响应
|
||||
if resp.response.Rcode == dns.RcodeSuccess {
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
} else if !hasBestResponse {
|
||||
// 没有带DNSSEC的响应时,保存第一个成功响应
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
// 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应
|
||||
if resp.response.Rcode == dns.RcodeSuccess || resp.response.Rcode == dns.RcodeNameError {
|
||||
// 检查当前使用的服务器是否是DNSSEC专用服务器
|
||||
for _, dnssecServer := range dnssecServers {
|
||||
if dnssecServer == resp.server {
|
||||
usedDNSSECServer = resp.server
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if resp.response.Rcode == dns.RcodeSuccess {
|
||||
// 处理成功响应
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
usedDNSServer = resp.server
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
} else if !hasBestResponse {
|
||||
// 没有带DNSSEC的响应时,保存第一个成功响应
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
usedDNSServer = resp.server
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
}
|
||||
} else if resp.response.Rcode == dns.RcodeNameError {
|
||||
// 处理NXDOMAIN响应
|
||||
// 如果还没有最佳响应,或者最佳响应也是NXDOMAIN,优先选择更快的NXDOMAIN响应
|
||||
if !hasBestResponse || bestResponse.Rcode == dns.RcodeNameError {
|
||||
// 如果还没有最佳响应,或者当前响应更快,更新最佳响应
|
||||
if !hasBestResponse || resp.rtt < bestRtt {
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
usedDNSServer = resp.server
|
||||
logger.Debug("找到NXDOMAIN最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 保存为备选响应
|
||||
if !hasBackup {
|
||||
@@ -900,21 +939,46 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
}
|
||||
}
|
||||
|
||||
// 如果响应成功,根据DNSSEC状态选择最佳响应
|
||||
if response.Rcode == dns.RcodeSuccess {
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
// 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应
|
||||
if response.Rcode == dns.RcodeSuccess || response.Rcode == dns.RcodeNameError {
|
||||
if response.Rcode == dns.RcodeSuccess {
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
usedDNSServer = selectedServer
|
||||
// 如果当前使用的服务器是DNSSEC专用服务器,同时设置usedDNSSECServer
|
||||
for _, dnssecServer := range dnssecServers {
|
||||
if dnssecServer == selectedServer {
|
||||
usedDNSSECServer = selectedServer
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", selectedServer, "rtt", rtt)
|
||||
} else {
|
||||
// 没有带DNSSEC的响应时,保存成功响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
usedDNSServer = selectedServer
|
||||
// 如果当前使用的服务器是DNSSEC专用服务器,同时设置usedDNSSECServer
|
||||
for _, dnssecServer := range dnssecServers {
|
||||
if dnssecServer == selectedServer {
|
||||
usedDNSSECServer = selectedServer
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", selectedServer, "rtt", rtt)
|
||||
}
|
||||
} else if response.Rcode == dns.RcodeNameError {
|
||||
// 处理NXDOMAIN响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", selectedServer, "rtt", rtt)
|
||||
} else {
|
||||
// 没有带DNSSEC的响应时,保存成功响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", selectedServer, "rtt", rtt)
|
||||
usedDNSServer = selectedServer
|
||||
logger.Debug("找到NXDOMAIN响应", "domain", domain, "server", selectedServer, "rtt", rtt)
|
||||
}
|
||||
// 保存为备选响应
|
||||
if !hasBackup {
|
||||
@@ -968,21 +1032,46 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
}
|
||||
}
|
||||
|
||||
// 如果响应成功,根据DNSSEC状态选择最佳响应
|
||||
if response.Rcode == dns.RcodeSuccess {
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
// 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应
|
||||
if response.Rcode == dns.RcodeSuccess || response.Rcode == dns.RcodeNameError {
|
||||
if response.Rcode == dns.RcodeSuccess {
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
usedDNSServer = fastestServer
|
||||
// 如果当前使用的服务器是DNSSEC专用服务器,同时设置usedDNSSECServer
|
||||
for _, dnssecServer := range dnssecServers {
|
||||
if dnssecServer == fastestServer {
|
||||
usedDNSSECServer = fastestServer
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", fastestServer, "rtt", rtt)
|
||||
} else {
|
||||
// 没有带DNSSEC的响应时,保存成功响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
usedDNSServer = fastestServer
|
||||
// 如果当前使用的服务器是DNSSEC专用服务器,同时设置usedDNSSECServer
|
||||
for _, dnssecServer := range dnssecServers {
|
||||
if dnssecServer == fastestServer {
|
||||
usedDNSSECServer = fastestServer
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", fastestServer, "rtt", rtt)
|
||||
}
|
||||
} else if response.Rcode == dns.RcodeNameError {
|
||||
// 处理NXDOMAIN响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", fastestServer, "rtt", rtt)
|
||||
} else {
|
||||
// 没有带DNSSEC的响应时,保存成功响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", fastestServer, "rtt", rtt)
|
||||
usedDNSServer = fastestServer
|
||||
logger.Debug("找到NXDOMAIN响应", "domain", domain, "server", fastestServer, "rtt", rtt)
|
||||
}
|
||||
// 保存为备选响应
|
||||
if !hasBackup {
|
||||
@@ -1050,21 +1139,52 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
}
|
||||
}
|
||||
|
||||
// 如果响应成功,根据DNSSEC状态选择最佳响应
|
||||
if resp.response.Rcode == dns.RcodeSuccess {
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
} else if !hasBestResponse {
|
||||
// 没有带DNSSEC的响应时,保存第一个成功响应
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
// 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应
|
||||
if resp.response.Rcode == dns.RcodeSuccess || resp.response.Rcode == dns.RcodeNameError {
|
||||
if resp.response.Rcode == dns.RcodeSuccess {
|
||||
// 优先选择带有DNSSEC记录的响应
|
||||
if containsDNSSEC {
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
hasDNSSECResponse = true
|
||||
usedDNSServer = resp.server
|
||||
// 如果当前使用的服务器是DNSSEC专用服务器,同时设置usedDNSSECServer
|
||||
for _, dnssecServer := range dnssecServers {
|
||||
if dnssecServer == resp.server {
|
||||
usedDNSSECServer = resp.server
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.Debug("找到带DNSSEC的最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
} else if !hasBestResponse {
|
||||
// 没有带DNSSEC的响应时,保存第一个成功响应
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
usedDNSServer = resp.server
|
||||
// 如果当前使用的服务器是DNSSEC专用服务器,同时设置usedDNSSECServer
|
||||
for _, dnssecServer := range dnssecServers {
|
||||
if dnssecServer == resp.server {
|
||||
usedDNSSECServer = resp.server
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.Debug("找到最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
}
|
||||
} else if resp.response.Rcode == dns.RcodeNameError {
|
||||
// 处理NXDOMAIN响应
|
||||
// 如果还没有最佳响应,或者最佳响应也是NXDOMAIN,优先选择更快的NXDOMAIN响应
|
||||
if !hasBestResponse || bestResponse.Rcode == dns.RcodeNameError {
|
||||
// 如果还没有最佳响应,或者当前响应更快,更新最佳响应
|
||||
if !hasBestResponse || resp.rtt < bestRtt {
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
usedDNSServer = resp.server
|
||||
logger.Debug("找到NXDOMAIN最佳响应", "domain", domain, "server", resp.server, "rtt", resp.rtt)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 保存为备选响应
|
||||
if !hasBackup {
|
||||
@@ -1137,6 +1257,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
containsDNSSEC := s.hasDNSSECRecords(resp.response)
|
||||
|
||||
if resp.response.Rcode == dns.RcodeSuccess {
|
||||
// 无论响应是否包含DNSSEC记录,只要使用了DNSSEC专用服务器,就设置usedDNSSECServer
|
||||
usedDNSSECServer = resp.server
|
||||
|
||||
// 验证DNSSEC记录
|
||||
signatureValid := s.verifyDNSSEC(resp.response)
|
||||
|
||||
@@ -1197,6 +1320,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
containsDNSSEC := s.hasDNSSECRecords(response)
|
||||
|
||||
if response.Rcode == dns.RcodeSuccess {
|
||||
// 无论响应是否包含DNSSEC记录,只要使用了DNSSEC专用服务器,就设置usedDNSSECServer
|
||||
usedDNSSECServer = selectedServer
|
||||
|
||||
// 验证DNSSEC记录
|
||||
signatureValid := s.verifyDNSSEC(response)
|
||||
|
||||
@@ -1257,6 +1383,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
containsDNSSEC := s.hasDNSSECRecords(response)
|
||||
|
||||
if response.Rcode == dns.RcodeSuccess {
|
||||
// 无论响应是否包含DNSSEC记录,只要使用了DNSSEC专用服务器,就设置usedDNSSECServer
|
||||
usedDNSSECServer = fastestServer
|
||||
|
||||
// 验证DNSSEC记录
|
||||
signatureValid := s.verifyDNSSEC(response)
|
||||
|
||||
@@ -1315,6 +1444,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
containsDNSSEC := s.hasDNSSECRecords(response)
|
||||
|
||||
if response.Rcode == dns.RcodeSuccess {
|
||||
// 无论响应是否包含DNSSEC记录,只要使用了DNSSEC专用服务器,就设置usedDNSSECServer
|
||||
usedDNSSECServer = dnssecServer
|
||||
|
||||
// 验证DNSSEC记录
|
||||
signatureValid := s.verifyDNSSEC(response)
|
||||
|
||||
@@ -1366,9 +1498,43 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
// 检查最佳响应是否包含DNSSEC记录
|
||||
bestHasDNSSEC := s.hasDNSSECRecords(bestResponse)
|
||||
|
||||
// 如果启用了DNSSEC且最佳响应不包含DNSSEC记录,使用upstreamDNS的解析结果
|
||||
// 如果启用了DNSSEC且最佳响应不包含DNSSEC记录,尝试使用本地解析
|
||||
if s.config.EnableDNSSEC && !bestHasDNSSEC {
|
||||
logger.Debug("最佳响应不包含DNSSEC记录,使用upstreamDNS的解析结果", "domain", domain)
|
||||
logger.Debug("最佳响应不包含DNSSEC记录,尝试使用本地解析", "domain", domain)
|
||||
if ip, exists := s.shieldManager.GetHostsIP(domain); exists {
|
||||
// 本地解析成功,构建响应
|
||||
localResponse := new(dns.Msg)
|
||||
localResponse.SetReply(r)
|
||||
localResponse.RecursionAvailable = true
|
||||
localResponse.AuthenticatedData = false
|
||||
localResponse.Rcode = dns.RcodeSuccess
|
||||
|
||||
if len(r.Question) > 0 {
|
||||
q := r.Question[0]
|
||||
answer := new(dns.A)
|
||||
answer.Hdr = dns.RR_Header{
|
||||
Name: q.Name,
|
||||
Rrtype: q.Qtype,
|
||||
Class: q.Qclass,
|
||||
Ttl: 300,
|
||||
}
|
||||
answer.A = net.ParseIP(ip)
|
||||
localResponse.Answer = append(localResponse.Answer, answer)
|
||||
}
|
||||
|
||||
// 记录解析域名统计
|
||||
s.updateResolvedDomainStats(domain)
|
||||
|
||||
// 更新域名的DNSSEC状态为false
|
||||
s.updateDomainDNSSECStatus(domain, false)
|
||||
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Allowed++
|
||||
})
|
||||
|
||||
logger.Debug("使用本地解析结果", "domain", domain, "ip", ip)
|
||||
return localResponse, 0, "", ""
|
||||
}
|
||||
}
|
||||
|
||||
// 记录解析域名统计
|
||||
@@ -1377,12 +1543,14 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
// 更新域名的DNSSEC状态
|
||||
if bestHasDNSSEC {
|
||||
s.updateDomainDNSSECStatus(domain, true)
|
||||
} else {
|
||||
s.updateDomainDNSSECStatus(domain, false)
|
||||
}
|
||||
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Allowed++
|
||||
})
|
||||
return bestResponse, bestRtt
|
||||
return bestResponse, bestRtt, usedDNSServer, usedDNSSECServer
|
||||
}
|
||||
|
||||
// 如果有备选响应,返回该响应
|
||||
@@ -1390,11 +1558,11 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
logger.Debug("使用备选响应,没有找到更好的结果", "domain", domain)
|
||||
// 记录解析域名统计
|
||||
s.updateResolvedDomainStats(domain)
|
||||
|
||||
// 更新统计信息
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Allowed++
|
||||
})
|
||||
return backupResponse, backupRtt
|
||||
return backupResponse, backupRtt, "", ""
|
||||
}
|
||||
|
||||
// 所有上游服务器都失败,返回服务器失败错误
|
||||
@@ -1407,12 +1575,12 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Errors++
|
||||
})
|
||||
return response, 0
|
||||
return response, 0, "", ""
|
||||
}
|
||||
|
||||
// forwardDNSRequest 转发DNS请求到上游服务器
|
||||
func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain string) {
|
||||
response, _ := s.forwardDNSRequestWithCache(r, domain)
|
||||
response, _, _, _ := s.forwardDNSRequestWithCache(r, domain)
|
||||
w.WriteMsg(response)
|
||||
}
|
||||
|
||||
@@ -1844,7 +2012,7 @@ func (s *Server) updateStats(update func(*Stats)) {
|
||||
}
|
||||
|
||||
// addQueryLog 添加查询日志
|
||||
func (s *Server) addQueryLog(clientIP, domain, queryType string, responseTime int64, result, blockRule, blockType string, fromCache, dnssec, edns bool) {
|
||||
func (s *Server) addQueryLog(clientIP, domain, queryType string, responseTime int64, result, blockRule, blockType string, fromCache, dnssec, edns bool, dnsServer, dnssecServer string) {
|
||||
// 获取IP地理位置
|
||||
location := s.getIpGeolocation(clientIP)
|
||||
|
||||
@@ -1862,6 +2030,8 @@ func (s *Server) addQueryLog(clientIP, domain, queryType string, responseTime in
|
||||
FromCache: fromCache,
|
||||
DNSSEC: dnssec,
|
||||
EDNS: edns,
|
||||
DNSServer: dnsServer,
|
||||
DNSSECServer: dnssecServer,
|
||||
}
|
||||
|
||||
// 添加到日志列表
|
||||
|
||||
Reference in New Issue
Block a user