From 1fd71ddfde6f73011360c4c610722b7aba9b1f15 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Sat, 4 Apr 2026 01:37:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dns/server.go | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/dns/server.go b/dns/server.go index ee80a0b..7eb5285 100644 --- a/dns/server.go +++ b/dns/server.go @@ -199,8 +199,8 @@ func NewServer(globalConfig *config.Config, shieldManager *shield.ShieldManager, Net: "udp", UDPSize: 4096, // 增加UDP缓冲区大小,支持更大的DNSSEC响应 }, - ctx: ctx, - cancel: cancel, + ctx: ctx, + cancel: cancel, stats: &Stats{ Queries: 0, Blocked: 0, @@ -237,7 +237,7 @@ func NewServer(globalConfig *config.Config, shieldManager *shield.ShieldManager, return &dns.Client{ Net: "udp", UDPSize: 4096, - Timeout: 5 * time.Second, // 默认超时时间,会在使用时覆盖 + Timeout: 2 * time.Second, // 默认超时时间,会在使用时覆盖(2 秒是合理的 DNS 查询超时) } }, }, @@ -339,7 +339,6 @@ func (s *Server) Start() error { // 重置stopped标志 - // 初始化威胁检测相关组件 s.initThreatDetection() @@ -1278,16 +1277,16 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 从池中获取客户端实例 client := s.clientPool.Get().(*dns.Client) - // 设置客户端参数 + // 设置客户端参数(确保在 Exchange 之前设置,避免竞态条件) client.Net = s.resolver.Net client.UDPSize = s.resolver.UDPSize - client.Timeout = defaultTimeout + client.Timeout = defaultTimeout // 使用配置的超时时间 // 发送请求并获取响应,确保服务器地址包含端口号 response, rtt, err := client.Exchange(r, normalizeDNSServerAddress(server)) responses <- serverResponse{response, rtt, server, err} - // 将客户端实例放回池中 + // 将客户端实例放回池中(不重置 Timeout,因为下次使用时会重新设置) s.clientPool.Put(client) }(upstream) } @@ -1853,21 +1852,35 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg }, 1) go func() { - resp, r, e := s.resolver.Exchange(r, normalizeDNSServerAddress(localServer)) + // 创建临时的 resolver,设置超时时间 + tempResolver := &dns.Client{ + Net: s.resolver.Net, + UDPSize: s.resolver.UDPSize, + Timeout: defaultTimeout, // 使用配置的超时时间 + } + resp, rtt, e := tempResolver.Exchange(r, normalizeDNSServerAddress(localServer)) resultChan <- struct { response *dns.Msg rtt time.Duration err error - }{resp, r, e} + }{resp, rtt, e} }() var localResponse *dns.Msg var rtt time.Duration var err error - // 直接获取结果,不使用上下文超时 - result := <-resultChan - localResponse, rtt, err = result.response, result.rtt, result.err + // 使用超时获取结果 + select { + case result := <-resultChan: + localResponse, rtt, err = result.response, result.rtt, result.err + case <-time.After(defaultTimeout): + // 超时 + logger.Debug("本地解析超时", "domain", domain, "server", localServer, "timeout", defaultTimeout) + // 超时后跳过本地解析 + localResponse = nil + err = fmt.Errorf("timeout") + } if err == nil && localResponse != nil { // 更新服务器统计信息 @@ -2685,7 +2698,7 @@ func (s *Server) GetQueryLogs(limit, offset int, sortField, sortDirection, resul // 如果新系统查询失败或没有数据,返回空列表 logger.Debug("新日志系统查询失败或无数据", "error", err, "logs", len(logs)) } - + // 返回空列表 return []QueryLog{} }