update
This commit is contained in:
+52
-56
@@ -1188,38 +1188,34 @@ func (s *Server) updateDNSSECServerMap() {
|
||||
}
|
||||
}
|
||||
|
||||
// forwardDNSRequestWithCache 转发DNS请求到上游服务器并返回响应
|
||||
// forwardDNSRequestWithCache 转发 DNS 请求到上游服务器并返回响应
|
||||
func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg, time.Duration, string, string) {
|
||||
// 始终支持EDNS
|
||||
// 始终支持 EDNS
|
||||
var udpSize uint16 = 4096
|
||||
var doFlag bool = s.config.EnableDNSSEC
|
||||
|
||||
// 检查域名是否匹配不验证DNSSEC的模式
|
||||
// 检查域名是否匹配不验证 DNSSEC 的模式
|
||||
noDNSSEC := false
|
||||
for _, pattern := range s.config.NoDNSSECDomains {
|
||||
if strings.Contains(domain, pattern) {
|
||||
noDNSSEC = true
|
||||
doFlag = false
|
||||
logger.Debug("域名匹配到不验证DNSSEC的模式", "domain", domain, "pattern", pattern)
|
||||
logger.Debug("域名匹配到不验证 DNSSEC 的模式", "domain", domain, "pattern", pattern)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 检查客户端请求是否包含EDNS记录
|
||||
// 检查客户端请求是否包含 EDNS 记录
|
||||
if opt := r.IsEdns0(); opt != nil {
|
||||
// 保留客户端的UDP缓冲区大小
|
||||
// 保留客户端的 UDP 缓冲区大小
|
||||
udpSize = opt.UDPSize()
|
||||
// 移除现有的EDNS记录,以便重新添加
|
||||
for i := range r.Extra {
|
||||
if r.Extra[i] == opt {
|
||||
r.Extra = append(r.Extra[:i], r.Extra[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加EDNS记录,设置适当的UDPSize和DO标志
|
||||
r.SetEdns0(udpSize, doFlag)
|
||||
// 创建请求的副本,避免修改原始请求
|
||||
query := r.Copy()
|
||||
|
||||
// 在副本上添加 EDNS 记录,设置适当的 UDPSize 和 DO 标志
|
||||
query.SetEdns0(udpSize, doFlag)
|
||||
|
||||
// DNSSEC专用服务器列表,从配置中获取
|
||||
dnssecServers := s.config.DNSSECUpstreamDNS
|
||||
@@ -1284,7 +1280,7 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg
|
||||
|
||||
// 使用配置中的超时时间
|
||||
defaultTimeout := time.Duration(s.config.QueryTimeout) * time.Millisecond
|
||||
logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultTimeout", defaultTimeout, "queryTimeout 配置", s.config.QueryTimeout)
|
||||
logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultTimeout", defaultTimeout, "queryTimeout 配置", s.config.QueryTimeout)
|
||||
|
||||
// 根据查询模式处理请求
|
||||
switch s.config.QueryMode {
|
||||
@@ -1307,7 +1303,7 @@ logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultT
|
||||
client.Timeout = defaultTimeout // 使用配置的超时时间
|
||||
|
||||
// 发送请求并获取响应,确保服务器地址包含端口号
|
||||
response, rtt, err := client.Exchange(r, normalizeDNSServerAddress(server))
|
||||
response, rtt, err := client.Exchange(query, normalizeDNSServerAddress(server))
|
||||
responses <- serverResponse{response, rtt, server, err}
|
||||
|
||||
// 将客户端实例放回池中(不重置 Timeout,因为下次使用时会重新设置)
|
||||
@@ -1411,7 +1407,7 @@ logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultT
|
||||
client.Timeout = defaultTimeout
|
||||
|
||||
// 只向一个服务器发送请求
|
||||
response, rtt, err := client.Exchange(r, normalizeDNSServerAddress(fastestServer))
|
||||
response, rtt, err := client.Exchange(query, normalizeDNSServerAddress(fastestServer))
|
||||
|
||||
// 将客户端实例放回池中
|
||||
s.clientPool.Put(client)
|
||||
@@ -1504,7 +1500,7 @@ logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultT
|
||||
go func(server string) {
|
||||
defer wg.Done()
|
||||
|
||||
// 创建带有超时的resolver
|
||||
// 创建带有超时的 resolver
|
||||
client := &dns.Client{
|
||||
Net: s.resolver.Net,
|
||||
UDPSize: s.resolver.UDPSize,
|
||||
@@ -1512,7 +1508,7 @@ logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultT
|
||||
}
|
||||
|
||||
// 发送请求并获取响应,确保服务器地址包含端口号
|
||||
response, rtt, err := client.Exchange(r, normalizeDNSServerAddress(server))
|
||||
response, rtt, err := client.Exchange(query, normalizeDNSServerAddress(server))
|
||||
responses <- serverResponse{response, rtt, server, err}
|
||||
}(upstream)
|
||||
}
|
||||
@@ -1568,44 +1564,44 @@ logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultT
|
||||
}
|
||||
|
||||
// 简化的快速返回逻辑:找到第一个成功响应或更快的响应
|
||||
// 对于不验证 DNSSEC 的域名,直接返回第一个成功响应(只发送一次)
|
||||
if noDNSSEC && !bestResponseSent {
|
||||
// 不验证 DNSSEC 的域名:返回第一个包含有效记录的成功响应
|
||||
if fastestResponse == nil || resp.rtt < fastestRtt {
|
||||
// 检查响应是否包含有效记录
|
||||
hasValidRecords := false
|
||||
if len(resp.response.Answer) > 0 {
|
||||
hasValidRecords = true
|
||||
} else if len(resp.response.Ns) > 0 {
|
||||
hasValidRecords = true
|
||||
} else if len(resp.response.Extra) > 0 {
|
||||
for _, rr := range resp.response.Extra {
|
||||
if rr.Header().Rrtype != dns.TypeOPT {
|
||||
hasValidRecords = true
|
||||
break
|
||||
// 对于不验证 DNSSEC 的域名,直接返回第一个成功响应(只发送一次)
|
||||
if noDNSSEC && !bestResponseSent {
|
||||
// 不验证 DNSSEC 的域名:返回第一个包含有效记录的成功响应
|
||||
if fastestResponse == nil || resp.rtt < fastestRtt {
|
||||
// 检查响应是否包含有效记录
|
||||
hasValidRecords := false
|
||||
if len(resp.response.Answer) > 0 {
|
||||
hasValidRecords = true
|
||||
} else if len(resp.response.Ns) > 0 {
|
||||
hasValidRecords = true
|
||||
} else if len(resp.response.Extra) > 0 {
|
||||
for _, rr := range resp.response.Extra {
|
||||
if rr.Header().Rrtype != dns.TypeOPT {
|
||||
hasValidRecords = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 只有包含有效记录才返回
|
||||
if hasValidRecords {
|
||||
fastestResponse = resp.response
|
||||
fastestRtt = resp.rtt
|
||||
fastestServer = resp.server
|
||||
fastestDnssecServer = dnssecServerForResponse
|
||||
fastestHasDnssec = false
|
||||
// 只有包含有效记录才返回
|
||||
if hasValidRecords {
|
||||
fastestResponse = resp.response
|
||||
fastestRtt = resp.rtt
|
||||
fastestServer = resp.server
|
||||
fastestDnssecServer = dnssecServerForResponse
|
||||
fastestHasDnssec = false
|
||||
|
||||
// 立即发送结果,快速返回(只发送一次)
|
||||
resultChan <- struct {
|
||||
response *dns.Msg
|
||||
rtt time.Duration
|
||||
usedServer string
|
||||
usedDnssecServer string
|
||||
}{fastestResponse, fastestRtt, fastestServer, fastestDnssecServer}
|
||||
bestResponseSent = true
|
||||
// 立即发送结果,快速返回(只发送一次)
|
||||
resultChan <- struct {
|
||||
response *dns.Msg
|
||||
rtt time.Duration
|
||||
usedServer string
|
||||
usedDnssecServer string
|
||||
}{fastestResponse, fastestRtt, fastestServer, fastestDnssecServer}
|
||||
bestResponseSent = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if resp.response.Rcode == dns.RcodeSuccess && !bestResponseSent {
|
||||
} else if resp.response.Rcode == dns.RcodeSuccess && !bestResponseSent {
|
||||
// 优先选择带有DNSSEC的响应
|
||||
if containsDNSSEC {
|
||||
// 如果这是第一个DNSSEC响应,或者比当前最快的DNSSEC响应更快
|
||||
@@ -1815,13 +1811,13 @@ logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultT
|
||||
}, 1)
|
||||
|
||||
go func() {
|
||||
// 创建带有超时的resolver
|
||||
// 创建带有超时的 resolver
|
||||
client := &dns.Client{
|
||||
Net: s.resolver.Net,
|
||||
UDPSize: s.resolver.UDPSize,
|
||||
Timeout: defaultTimeout,
|
||||
}
|
||||
response, rtt, err := client.Exchange(r, normalizeDNSServerAddress(selectedDnssecServer))
|
||||
response, rtt, err := client.Exchange(query, normalizeDNSServerAddress(selectedDnssecServer))
|
||||
resultChan <- struct {
|
||||
response *dns.Msg
|
||||
rtt time.Duration
|
||||
@@ -1924,7 +1920,7 @@ logger.Debug("并行查询超时设置", "domain", r.Question[0].Name, "defaultT
|
||||
UDPSize: s.resolver.UDPSize,
|
||||
Timeout: defaultTimeout, // 使用配置的超时时间
|
||||
}
|
||||
resp, rtt, e := tempResolver.Exchange(r, normalizeDNSServerAddress(localServer))
|
||||
resp, rtt, e := tempResolver.Exchange(query, normalizeDNSServerAddress(localServer))
|
||||
resultChan <- struct {
|
||||
response *dns.Msg
|
||||
rtt time.Duration
|
||||
|
||||
Reference in New Issue
Block a user