强化domainSpecificDNS逻辑,增加DNS后缀功能
This commit is contained in:
@@ -485,8 +485,47 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
return
|
||||
}
|
||||
|
||||
// 缓存未命中,转发到上游DNS服务器
|
||||
response, rtt := s.forwardDNSRequestWithCache(r, domain)
|
||||
// 缓存未命中,处理DNS请求
|
||||
var response *dns.Msg
|
||||
var rtt time.Duration
|
||||
var queryAttempts []string
|
||||
|
||||
// 1. 首先尝试直接查询原始域名
|
||||
queryAttempts = append(queryAttempts, domain)
|
||||
response, rtt = s.forwardDNSRequestWithCache(r, domain)
|
||||
|
||||
// 2. 如果直接查询失败且配置了prefixDomain,尝试添加前缀
|
||||
if (response == nil || response.Rcode != dns.RcodeSuccess) && len(s.config.PrefixDomain) > 0 {
|
||||
logger.Debug("直接查询失败,尝试使用prefixDomain", "domain", domain, "prefixDomain", s.config.PrefixDomain)
|
||||
|
||||
// 保存原始请求
|
||||
originalQuestion := r.Question[0]
|
||||
|
||||
// 遍历所有prefixDomain,尝试添加前缀
|
||||
for _, prefix := range s.config.PrefixDomain {
|
||||
// 构建完整域名
|
||||
fullDomain := domain + "." + prefix
|
||||
queryAttempts = append(queryAttempts, fullDomain)
|
||||
logger.Debug("尝试查询完整域名", "fullDomain", fullDomain)
|
||||
|
||||
// 创建新的请求消息
|
||||
newReq := r.Copy()
|
||||
// 更新查询域名
|
||||
newReq.Question[0] = dns.Question{
|
||||
Name: fullDomain + ".", // 域名需要以点结尾
|
||||
Qtype: originalQuestion.Qtype,
|
||||
Qclass: originalQuestion.Qclass,
|
||||
}
|
||||
|
||||
// 转发请求
|
||||
response, rtt = s.forwardDNSRequestWithCache(newReq, fullDomain)
|
||||
if response != nil && response.Rcode == dns.RcodeSuccess {
|
||||
logger.Debug("使用prefixDomain查询成功", "fullDomain", fullDomain, "originalDomain", domain)
|
||||
break // 找到成功的响应,退出循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if response != nil {
|
||||
// 如果客户端请求包含EDNS记录,确保响应也包含EDNS
|
||||
if opt := r.IsEdns0(); opt != nil {
|
||||
@@ -693,6 +732,25 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
// DNSSEC专用服务器列表,从配置中获取
|
||||
dnssecServers := s.config.DNSSECUpstreamDNS
|
||||
|
||||
// 选择合适的上游DNS服务器列表
|
||||
// 1. 首先检查是否有域名特定的DNS服务器配置
|
||||
var selectedUpstreamDNS []string
|
||||
var domainMatched bool
|
||||
|
||||
for matchStr, dnsServers := range s.config.DomainSpecificDNS {
|
||||
if strings.Contains(domain, matchStr) {
|
||||
selectedUpstreamDNS = dnsServers
|
||||
domainMatched = true
|
||||
logger.Debug("域名匹配到特定DNS服务器配置", "domain", domain, "matchStr", matchStr, "dnsServers", dnsServers)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 如果没有匹配的域名特定配置,使用默认的上游DNS服务器
|
||||
if !domainMatched {
|
||||
selectedUpstreamDNS = s.config.UpstreamDNS
|
||||
}
|
||||
|
||||
// 1. 首先尝试所有配置的上游DNS服务器
|
||||
var bestResponse *dns.Msg
|
||||
var bestRtt time.Duration
|
||||
@@ -706,7 +764,7 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
switch s.config.QueryMode {
|
||||
case "parallel":
|
||||
// 并行请求模式 - 优化版:添加超时处理和快速响应返回
|
||||
responses := make(chan serverResponse, len(s.config.UpstreamDNS))
|
||||
responses := make(chan serverResponse, len(selectedUpstreamDNS))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// 超时上下文
|
||||
@@ -714,7 +772,7 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
defer cancel()
|
||||
|
||||
// 向所有上游服务器并行发送请求
|
||||
for _, upstream := range s.config.UpstreamDNS {
|
||||
for _, upstream := range selectedUpstreamDNS {
|
||||
wg.Add(1)
|
||||
go func(server string) {
|
||||
defer wg.Done()
|
||||
@@ -806,7 +864,7 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
case "loadbalance":
|
||||
// 负载均衡模式 - 使用加权随机选择算法
|
||||
// 1. 选择一个加权随机服务器
|
||||
selectedServer := s.selectWeightedRandomServer(s.config.UpstreamDNS)
|
||||
selectedServer := s.selectWeightedRandomServer(selectedUpstreamDNS)
|
||||
if selectedServer != "" {
|
||||
response, rtt, err := s.resolver.Exchange(r, selectedServer)
|
||||
if err == nil && response != nil {
|
||||
@@ -874,7 +932,7 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
case "fastest-ip":
|
||||
// 最快的IP地址模式 - 使用TCP连接速度测量选择最快服务器
|
||||
// 1. 选择最快的服务器
|
||||
fastestServer := s.selectFastestServer(s.config.UpstreamDNS)
|
||||
fastestServer := s.selectFastestServer(selectedUpstreamDNS)
|
||||
if fastestServer != "" {
|
||||
response, rtt, err := s.resolver.Exchange(r, fastestServer)
|
||||
if err == nil && response != nil {
|
||||
@@ -941,11 +999,11 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
|
||||
default:
|
||||
// 默认使用并行请求模式
|
||||
responses := make(chan serverResponse, len(s.config.UpstreamDNS))
|
||||
responses := make(chan serverResponse, len(selectedUpstreamDNS))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// 向所有上游服务器并行发送请求
|
||||
for _, upstream := range s.config.UpstreamDNS {
|
||||
for _, upstream := range selectedUpstreamDNS {
|
||||
wg.Add(1)
|
||||
go func(server string) {
|
||||
defer wg.Done()
|
||||
@@ -1020,7 +1078,8 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
}
|
||||
|
||||
// 2. 当启用DNSSEC且没有找到带DNSSEC的响应时,向DNSSEC专用服务器发送请求
|
||||
if s.config.EnableDNSSEC && !hasDNSSECResponse {
|
||||
// 但如果域名匹配了domainSpecificDNS配置,则不使用DNSSEC专用服务器,只使用指定的DNS服务器
|
||||
if s.config.EnableDNSSEC && !hasDNSSECResponse && !domainMatched {
|
||||
logger.Debug("向DNSSEC专用服务器发送请求", "domain", domain)
|
||||
|
||||
// 增加DNSSEC查询计数
|
||||
@@ -1098,7 +1157,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
|
||||
// 优先使用DNSSEC专用服务器的响应,尤其是带有DNSSEC记录的
|
||||
if containsDNSSEC {
|
||||
// 即使之前有最佳响应,也优先使用DNSSEC专用服务器的DNSSEC响应
|
||||
bestResponse = resp.response
|
||||
bestRtt = resp.rtt
|
||||
hasBestResponse = true
|
||||
@@ -1159,7 +1217,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
|
||||
// 优先使用DNSSEC专用服务器的响应,尤其是带有DNSSEC记录的
|
||||
if containsDNSSEC {
|
||||
// 即使之前有最佳响应,也优先使用DNSSEC专用服务器的DNSSEC响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
@@ -1220,7 +1277,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
|
||||
// 优先使用DNSSEC专用服务器的响应,尤其是带有DNSSEC记录的
|
||||
if containsDNSSEC {
|
||||
// 即使之前有最佳响应,也优先使用DNSSEC专用服务器的DNSSEC响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
@@ -1279,7 +1335,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
|
||||
// 优先使用DNSSEC专用服务器的响应,尤其是带有DNSSEC记录的
|
||||
if containsDNSSEC {
|
||||
// 即使之前有最佳响应,也优先使用DNSSEC专用服务器的DNSSEC响应
|
||||
bestResponse = response
|
||||
bestRtt = rtt
|
||||
hasBestResponse = true
|
||||
|
||||
Reference in New Issue
Block a user