diff --git a/dns-server b/dns-server index 7af9e36..bf5214f 100755 Binary files a/dns-server and b/dns-server differ diff --git a/dns-server.log b/dns-server.log index 9e0805a..18babf7 100644 --- a/dns-server.log +++ b/dns-server.log @@ -131,3 +131,102 @@ time="2025-11-23T18:08:48+08:00" level=debug msg="接收到DNS查询" client="10 time="2025-11-23T18:08:48+08:00" level=debug msg="DNS查询成功" domain=h5hosting.dbankcdn.com rtt=7.025853ms server="223.5.5.5:53" time="2025-11-23T18:08:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:12618" domain=metrics1.data.hicloud.com type=1 time="2025-11-23T18:08:48+08:00" level=debug msg="DNS查询成功" domain=metrics1.data.hicloud.com rtt=5.85395ms server="223.5.5.5:53" +time="2025-11-23T18:14:50+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:18455" domain=dns.weixin.qq.com.cn type=1 +time="2025-11-23T18:14:50+08:00" level=debug msg="DNS查询成功" domain=dns.weixin.qq.com.cn rtt=5.279561ms server="223.5.5.5:53" +time="2025-11-23T18:15:31+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:51626" domain=tvax4.sinaimg.cn type=1 +time="2025-11-23T18:15:31+08:00" level=debug msg="DNS查询成功" domain=tvax4.sinaimg.cn rtt=5.918625ms server="223.5.5.5:53" +time="2025-11-23T18:15:57+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:5242" domain=tsms-drcn.security.dbankcloud.cn type=1 +time="2025-11-23T18:15:57+08:00" level=debug msg="DNS查询成功" domain=tsms-drcn.security.dbankcloud.cn rtt=6.292185ms server="223.5.5.5:53" +time="2025-11-23T18:17:24+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:3812" domain=login.microsoftonline.com type=1 +time="2025-11-23T18:17:24+08:00" level=debug msg="DNS查询成功" domain=login.microsoftonline.com rtt=8.062737ms server="223.5.5.5:53" +time="2025-11-23T18:20:29+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:24579" domain=apd-pcdnwxlogin.teg.tencent-cloud.net type=1 +time="2025-11-23T18:20:29+08:00" level=debug msg="DNS查询成功" domain=apd-pcdnwxlogin.teg.tencent-cloud.net rtt=6.721482ms server="223.5.5.5:53" +time="2025-11-23T18:22:01+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:46378" domain=nearby-find-api-drcn.hms.dbankcloud.com type=1 +time="2025-11-23T18:22:01+08:00" level=debug msg="DNS查询成功" domain=nearby-find-api-drcn.hms.dbankcloud.com rtt=5.399528ms server="223.5.5.5:53" +time="2025-11-23T18:22:37+08:00" level=info msg="正在关闭服务..." +time="2025-11-23T18:22:37+08:00" level=info msg="DNS服务器已停止" +time="2025-11-23T18:22:37+08:00" level=error msg="HTTP控制台服务器启动失败" error="http: Server closed" +time="2025-11-23T18:22:37+08:00" level=info msg="HTTP控制台服务器已停止" +time="2025-11-23T18:22:37+08:00" level=info msg="所有服务已关闭" +time="2025-11-23T18:22:37+08:00" level=warning msg="日志系统已关闭" +time="2025-11-23T18:28:33+08:00" level=error msg="获取远程规则失败" error="远程服务器返回错误状态码: 404" url="https://example.com/rules.txt" +time="2025-11-23T18:28:33+08:00" level=info msg="规则加载完成,域名规则: 2, 排除规则: 0, 正则规则: 2, hosts规则: 3" +time="2025-11-23T18:28:33+08:00" level=info msg="DNS服务器已启动,监听端口: 53" +time="2025-11-23T18:28:33+08:00" level=info msg="HTTP控制台已启动,监听端口: 8080" +time="2025-11-23T18:28:33+08:00" level=info msg="DNS TCP服务器启动,监听端口: 53" +time="2025-11-23T18:28:33+08:00" level=info msg="DNS UDP服务器启动,监听端口: 53" +time="2025-11-23T18:28:33+08:00" level=info msg="HTTP控制台服务器启动,监听地址: 0.0.0.0:8080" +time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55569" domain=adjust.net.amazehome.xyz type=1 +time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55569" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55570" domain=adjust.net.amazehome.xyz type=28 +time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55570" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55571" domain=adjust.net type=1 +time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55571" domain=adjust.net +time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55572" domain=adjust.net type=28 +time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55572" domain=adjust.net +time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62375" domain=adjust.net.amazehome.xyz type=1 +time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62375" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62376" domain=adjust.net.amazehome.xyz type=28 +time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62376" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62377" domain=adjust.net type=1 +time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62377" domain=adjust.net +time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62378" domain=adjust.net type=28 +time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62378" domain=adjust.net +time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55979" domain=adjust.net.amazehome.xyz type=1 +time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55979" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55980" domain=adjust.net.amazehome.xyz type=28 +time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55980" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55981" domain=adjust.net type=1 +time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55981" domain=adjust.net +time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55982" domain=adjust.net type=28 +time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55982" domain=adjust.net +time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56717" domain=adjust.net.amazehome.xyz type=1 +time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56717" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56718" domain=adjust.net.amazehome.xyz type=28 +time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56718" domain=adjust.net.amazehome.xyz +time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56719" domain=adjust.net type=1 +time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56719" domain=adjust.net +time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56720" domain=adjust.net type=28 +time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56720" domain=adjust.net +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64531" domain=so.com.amazehome.xyz type=1 +time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=28.942261ms server="223.5.5.5:53" +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64532" domain=so.com.amazehome.xyz type=28 +time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=66.744527ms server="223.5.5.5:53" +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64533" domain=so.com type=1 +time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=6.238678ms server="223.5.5.5:53" +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64534" domain=so.com type=28 +time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=76.33228ms server="223.5.5.5:53" +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64535" domain=so.com.amazehome.xyz type=1 +time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=65.586366ms server="223.5.5.5:53" +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55838" domain=so.com.amazehome.xyz type=28 +time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=66.617532ms server="223.5.5.5:53" +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55839" domain=so.com type=1 +time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=3.690694ms server="223.5.5.5:53" +time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55840" domain=so.com type=28 +time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=24.691944ms server="223.5.5.5:53" +time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52832" domain=so.com.amazehome.xyz type=1 +time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=67.631415ms server="223.5.5.5:53" +time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52833" domain=so.com.amazehome.xyz type=28 +time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=67.775451ms server="223.5.5.5:53" +time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52834" domain=so.com type=1 +time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=6.394435ms server="223.5.5.5:53" +time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52835" domain=so.com type=28 +time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=41.126372ms server="223.5.5.5:53" +time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49722" domain=tracking.ad.qq.com.amazehome.xyz type=1 +time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49722" domain=tracking.ad.qq.com.amazehome.xyz +time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49723" domain=tracking.ad.qq.com.amazehome.xyz type=28 +time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49723" domain=tracking.ad.qq.com.amazehome.xyz +time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49724" domain=tracking.ad.qq.com type=1 +time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49724" domain=tracking.ad.qq.com +time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49725" domain=tracking.ad.qq.com type=28 +time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49725" domain=tracking.ad.qq.com +time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64389" domain=ads.qq.com.amazehome.xyz type=1 +time="2025-11-23T18:30:48+08:00" level=debug msg="DNS查询成功" domain=ads.qq.com.amazehome.xyz rtt=23.436825ms server="223.5.5.5:53" +time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64390" domain=ads.qq.com.amazehome.xyz type=28 +time="2025-11-23T18:30:48+08:00" level=debug msg="DNS查询成功" domain=ads.qq.com.amazehome.xyz rtt=26.677483ms server="223.5.5.5:53" +time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64391" domain=ads.qq.com type=1 +time="2025-11-23T18:30:48+08:00" level=error msg="DNS查询失败" domain=ads.qq.com +time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64392" domain=ads.qq.com type=28 +time="2025-11-23T18:30:48+08:00" level=error msg="DNS查询失败" domain=ads.qq.com +time="2025-11-23T18:31:49+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:8360" domain=self.events.data.microsoft.com type=65 +time="2025-11-23T18:31:49+08:00" level=debug msg="DNS查询成功" domain=self.events.data.microsoft.com rtt=14.34768ms server="223.5.5.5:53" diff --git a/dns/server.go b/dns/server.go index b23f016..c3c38a6 100644 --- a/dns/server.go +++ b/dns/server.go @@ -25,19 +25,21 @@ type BlockedDomain struct { // Server DNS服务器 type Server struct { - config *config.DNSConfig - shieldConfig *config.ShieldConfig - shieldManager *shield.ShieldManager - server *dns.Server - resolver *dns.Client - ctx context.Context - cancel context.CancelFunc - statsMutex sync.Mutex - stats *Stats - blockedDomainsMutex sync.RWMutex - blockedDomains map[string]*BlockedDomain - hourlyStatsMutex sync.RWMutex - hourlyStats map[string]int64 // 按小时统计屏蔽数量 + config *config.DNSConfig + shieldConfig *config.ShieldConfig + shieldManager *shield.ShieldManager + server *dns.Server + resolver *dns.Client + ctx context.Context + cancel context.CancelFunc + statsMutex sync.Mutex + stats *Stats + blockedDomainsMutex sync.RWMutex + blockedDomains map[string]*BlockedDomain + resolvedDomainsMutex sync.RWMutex + resolvedDomains map[string]*BlockedDomain // 用于记录解析的域名 + hourlyStatsMutex sync.RWMutex + hourlyStats map[string]int64 // 按小时统计屏蔽数量 } // Stats DNS服务器统计信息 @@ -68,8 +70,9 @@ func NewServer(config *config.DNSConfig, shieldConfig *config.ShieldConfig, shie Allowed: 0, Errors: 0, }, - blockedDomains: make(map[string]*BlockedDomain), - hourlyStats: make(map[string]int64), + blockedDomains: make(map[string]*BlockedDomain), + resolvedDomains: make(map[string]*BlockedDomain), + hourlyStats: make(map[string]int64), } } @@ -184,6 +187,16 @@ func (s *Server) handleHostsResponse(w dns.ResponseWriter, r *dns.Msg, ip string response.Answer = append(response.Answer, answer) } + // 记录解析域名统计 + domain := "" + if len(r.Question) > 0 { + domain = r.Question[0].Name + if len(domain) > 0 && domain[len(domain)-1] == '.' { + domain = domain[:len(domain)-1] + } + s.updateResolvedDomainStats(domain) + } + w.WriteMsg(response) s.updateStats(func(stats *Stats) { stats.Allowed++ @@ -272,6 +285,9 @@ func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain stri w.WriteMsg(response) logger.Debug("DNS查询成功", "domain", domain, "rtt", rtt, "server", upstream) + // 记录解析域名统计 + s.updateResolvedDomainStats(domain) + s.updateStats(func(stats *Stats) { stats.Allowed++ }) @@ -311,7 +327,26 @@ func (s *Server) updateBlockedDomainStats(domain string) { // 更新小时统计 hourKey := time.Now().Format("2006-01-02-15") + s.hourlyStatsMutex.Lock() s.hourlyStats[hourKey]++ + s.hourlyStatsMutex.Unlock() +} + +// updateResolvedDomainStats 更新解析域名统计 +func (s *Server) updateResolvedDomainStats(domain string) { + s.resolvedDomainsMutex.Lock() + defer s.resolvedDomainsMutex.Unlock() + + if entry, exists := s.resolvedDomains[domain]; exists { + entry.Count++ + entry.LastSeen = time.Now() + } else { + s.resolvedDomains[domain] = &BlockedDomain{ + Domain: domain, + Count: 1, + LastSeen: time.Now(), + } + } } // updateStats 更新统计信息 @@ -359,6 +394,29 @@ func (s *Server) GetTopBlockedDomains(limit int) []BlockedDomain { return domains } +// GetTopResolvedDomains 获取TOP解析域名 +func (s *Server) GetTopResolvedDomains(limit int) []BlockedDomain { + s.resolvedDomainsMutex.RLock() + defer s.resolvedDomainsMutex.RUnlock() + + // 转换为切片 + domains := make([]BlockedDomain, 0, len(s.resolvedDomains)) + for _, entry := range s.resolvedDomains { + domains = append(domains, *entry) + } + + // 按数量排序 + sort.Slice(domains, func(i, j int) bool { + return domains[i].Count > domains[j].Count + }) + + // 返回限制数量 + if len(domains) > limit { + return domains[:limit] + } + return domains +} + // GetRecentBlockedDomains 获取最近屏蔽的域名列表 func (s *Server) GetRecentBlockedDomains(limit int) []BlockedDomain { s.blockedDomainsMutex.RLock() diff --git a/http/server.go b/http/server.go index 98f800a..6961a2b 100644 --- a/http/server.go +++ b/http/server.go @@ -46,6 +46,7 @@ func (s *Server) Start() error { mux.HandleFunc("/api/config", s.handleConfig) // 添加统计相关接口 mux.HandleFunc("/api/top-blocked", s.handleTopBlockedDomains) + mux.HandleFunc("/api/top-resolved", s.handleTopResolvedDomains) mux.HandleFunc("/api/recent-blocked", s.handleRecentBlockedDomains) mux.HandleFunc("/api/hourly-stats", s.handleHourlyStats) } @@ -114,6 +115,28 @@ func (s *Server) handleTopBlockedDomains(w http.ResponseWriter, r *http.Request) json.NewEncoder(w).Encode(result) } +// handleTopResolvedDomains 处理获取最常解析的域名请求 +func (s *Server) handleTopResolvedDomains(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + domains := s.dnsServer.GetTopResolvedDomains(10) + + // 转换为前端需要的格式 + result := make([]map[string]interface{}, len(domains)) + for i, domain := range domains { + result[i] = map[string]interface{}{ + "domain": domain.Domain, + "count": domain.Count, + } + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(result) +} + // handleRecentBlockedDomains 处理最近屏蔽域名请求 func (s *Server) handleRecentBlockedDomains(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { diff --git a/shield/manager.go b/shield/manager.go index 68a6f7a..63bdaa0 100644 --- a/shield/manager.go +++ b/shield/manager.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "regexp" + "sort" "strings" "sync" "time" @@ -30,6 +31,8 @@ type ShieldManager struct { regexRules []regexRule regexExceptions []regexRule hostsMap map[string]string + blockedDomainsCount map[string]int + resolvedDomainsCount map[string]int rulesMutex sync.RWMutex updateCtx context.Context updateCancel context.CancelFunc @@ -46,6 +49,8 @@ func NewShieldManager(config *config.ShieldConfig) *ShieldManager { regexRules: []regexRule{}, regexExceptions: []regexRule{}, hostsMap: make(map[string]string), + blockedDomainsCount: make(map[string]int), + resolvedDomainsCount: make(map[string]int), updateCtx: ctx, updateCancel: cancel, } @@ -62,6 +67,7 @@ func (m *ShieldManager) LoadRules() error { m.regexRules = []regexRule{} m.regexExceptions = []regexRule{} m.hostsMap = make(map[string]string) + // 保留计数数据,不随规则重新加载而清空 // 加载本地规则文件 if err := m.loadLocalRules(); err != nil { @@ -380,6 +386,106 @@ func (m *ShieldManager) IsBlocked(domain string) bool { return false } +// RecordBlockedDomain 记录被屏蔽的域名 +func (m *ShieldManager) RecordBlockedDomain(domain string) { + m.rulesMutex.Lock() + defer m.rulesMutex.Unlock() + m.blockedDomainsCount[domain]++ +} + +// RecordResolvedDomain 记录被解析的域名 +func (m *ShieldManager) RecordResolvedDomain(domain string) { + m.rulesMutex.Lock() + defer m.rulesMutex.Unlock() + m.resolvedDomainsCount[domain]++ +} + +// GetTopBlockedDomains 获取最常被屏蔽的域名 +func (m *ShieldManager) GetTopBlockedDomains(limit int) []map[string]interface{} { + m.rulesMutex.RLock() + defer m.rulesMutex.RUnlock() + + // 如果没有数据,返回空数组 + if len(m.blockedDomainsCount) == 0 { + return []map[string]interface{}{} + } + + // 转换为切片以便排序 + type domainCount struct { + Domain string + Count int + } + + var domains []domainCount + for domain, count := range m.blockedDomainsCount { + domains = append(domains, domainCount{Domain: domain, Count: count}) + } + + // 按计数降序排序 + sort.Slice(domains, func(i, j int) bool { + return domains[i].Count > domains[j].Count + }) + + // 限制返回数量 + if len(domains) > limit { + domains = domains[:limit] + } + + // 转换为API响应格式 + result := make([]map[string]interface{}, len(domains)) + for i, item := range domains { + result[i] = map[string]interface{}{ + "domain": item.Domain, + "count": item.Count, + } + } + + return result +} + +// GetTopResolvedDomains 获取最常被解析的域名 +func (m *ShieldManager) GetTopResolvedDomains(limit int) []map[string]interface{} { + m.rulesMutex.RLock() + defer m.rulesMutex.RUnlock() + + // 如果没有数据,返回空数组 + if len(m.resolvedDomainsCount) == 0 { + return []map[string]interface{}{} + } + + // 转换为切片以便排序 + type domainCount struct { + Domain string + Count int + } + + var domains []domainCount + for domain, count := range m.resolvedDomainsCount { + domains = append(domains, domainCount{Domain: domain, Count: count}) + } + + // 按计数降序排序 + sort.Slice(domains, func(i, j int) bool { + return domains[i].Count > domains[j].Count + }) + + // 限制返回数量 + if len(domains) > limit { + domains = domains[:limit] + } + + // 转换为API响应格式 + result := make([]map[string]interface{}, len(domains)) + for i, item := range domains { + result[i] = map[string]interface{}{ + "domain": item.Domain, + "count": item.Count, + } + } + + return result +} + // GetHostsIP 获取hosts文件中的IP映射 func (m *ShieldManager) GetHostsIP(domain string) (string, bool) { m.rulesMutex.RLock() diff --git a/static/index.html b/static/index.html index bd74d67..2010eca 100644 --- a/static/index.html +++ b/static/index.html @@ -1567,40 +1567,37 @@ function loadRules() { document.getElementById('top-blocked-domains').innerHTML = '
加载失败
暂无解析域名统计
加载失败