diff --git a/dns/server.go b/dns/server.go index ae0a74c..191a778 100644 --- a/dns/server.go +++ b/dns/server.go @@ -102,11 +102,11 @@ type Server struct { saveDone chan struct{} // 用于通知保存协程停止 stopped bool // 服务器是否已经停止 stoppedMutex sync.Mutex // 保护stopped标志的互斥锁 - + // IP地理位置缓存 - ipGeolocationCache map[string]*IPGeolocation // IP地址到地理位置的映射 - ipGeolocationCacheMutex sync.RWMutex // 保护IP地理位置缓存的互斥锁 - ipGeolocationCacheTTL time.Duration // 缓存有效期 + ipGeolocationCache map[string]*IPGeolocation // IP地址到地理位置的映射 + ipGeolocationCacheMutex sync.RWMutex // 保护IP地理位置缓存的互斥锁 + ipGeolocationCacheTTL time.Duration // 缓存有效期 } // Stats DNS服务器统计信息 @@ -159,8 +159,8 @@ func NewServer(config *config.DNSConfig, shieldConfig *config.ShieldConfig, shie saveDone: make(chan struct{}), stopped: false, // 初始化为未停止状态 // IP地理位置缓存初始化 - ipGeolocationCache: make(map[string]*IPGeolocation), - ipGeolocationCacheTTL: 24 * time.Hour, // 缓存有效期24小时 + ipGeolocationCache: make(map[string]*IPGeolocation), + ipGeolocationCacheTTL: 24 * time.Hour, // 缓存有效期24小时 } // 加载已保存的统计数据 @@ -594,7 +594,7 @@ func (s *Server) updateStats(update func(*Stats)) { func (s *Server) addQueryLog(clientIP, domain, queryType string, responseTime int64, result, blockRule, blockType string) { // 获取IP地理位置 location := s.getIpGeolocation(clientIP) - + // 创建日志记录 log := QueryLog{ Timestamp: time.Now(), @@ -928,11 +928,60 @@ func (s *Server) GetMonthlyStats() map[string]int64 { return result } +// isPrivateIP 检测IP地址是否为内网IP +func isPrivateIP(ip string) bool { + // 解析IP地址 + parsedIP := net.ParseIP(ip) + if parsedIP == nil { + return false + } + + // 检查IPv4内网地址 + if ipv4 := parsedIP.To4(); ipv4 != nil { + // 10.0.0.0/8 + if ipv4[0] == 10 { + return true + } + // 172.16.0.0/12 + if ipv4[0] == 172 && (ipv4[1] >= 16 && ipv4[1] <= 31) { + return true + } + // 192.168.0.0/16 + if ipv4[0] == 192 && ipv4[1] == 168 { + return true + } + // 127.0.0.0/8 (localhost) + if ipv4[0] == 127 { + return true + } + // 169.254.0.0/16 (链路本地地址) + if ipv4[0] == 169 && ipv4[1] == 254 { + return true + } + return false + } + + // 检查IPv6内网地址 + // ::1/128 (localhost) + if parsedIP.IsLoopback() { + return true + } + // fc00::/7 (唯一本地地址) + if parsedIP[0]&0xfc == 0xfc { + return true + } + // fe80::/10 (链路本地地址) + if parsedIP[0]&0xfe == 0xfe && parsedIP[1]&0xc0 == 0x80 { + return true + } + return false +} + // getIpGeolocation 获取IP地址的地理位置信息 func (s *Server) getIpGeolocation(ip string) string { - // 检查IP是否为本地地址 - if ip == "127.0.0.1" || ip == "::1" { - return "本地 本地" + // 检查IP是否为本地或内网地址 + if isPrivateIP(ip) { + return "内网 内网" } // 先检查缓存