lolly/internal/utils/ipallowlist.go
xfy 91e04222b3 refactor: 统一 IP 白名单解析和 excludeSet 构建
Batch 1 重构:
- 新增 utils.ParseIPAllowList 统一 IP/CIDR 解析(含 localhost 特殊处理)
- pprof.go/status.go/purge.go 改用统一函数,减少 ~66 行重复代码
- 新增 loadbalance.buildExcludeSet 统一排除集合构建
- 更新 pprof_test.go 适配统一字段 allowed []net.IPNet

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 16:18:52 +08:00

93 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package utils 提供通用工具函数
package utils
import (
"net"
)
// ParseIPAllowList 解析 IP/CIDR 白名单列表。
//
// 支持格式:
// - CIDR 格式192.168.1.0/24、::1/128
// - 单个 IP192.168.1.1(自动转换为 /32 或 /128
// - 特殊值 "localhost":映射为 127.0.0.1/32 和 ::1/128
//
// 参数:
// - allow: IP/CIDR 字符串列表
//
// 返回值:
// - []net.IPNet: 解析后的网络列表
// - error: 解析失败时返回错误
func ParseIPAllowList(allow []string) ([]net.IPNet, error) {
if len(allow) == 0 {
return nil, nil
}
result := make([]net.IPNet, 0, len(allow)+2) // +2 for localhost expansion
for _, cidr := range allow {
// 处理 localhost 特殊情况
if cidr == "localhost" {
// localhost 解析为 127.0.0.1 和 ::1
if v4Net, err := parseCIDR("127.0.0.1/32"); err == nil {
result = append(result, *v4Net)
}
if v6Net, err := parseCIDR("::1/128"); err == nil {
result = append(result, *v6Net)
}
continue
}
// 尝试 CIDR 解析
_, network, err := net.ParseCIDR(cidr)
if err == nil && network != nil {
result = append(result, *network)
continue
}
// fallback: 尝试作为单个 IP 解析
ip := net.ParseIP(cidr)
if ip == nil {
return nil, err // 返回原始 CIDR 解析错误
}
// 转换为 CIDR 格式
var ipNet *net.IPNet
if ip.To4() != nil {
ipNet, _ = parseCIDR(cidr + "/32")
} else {
ipNet, _ = parseCIDR(cidr + "/128")
}
if ipNet != nil {
result = append(result, *ipNet)
}
}
return result, nil
}
// parseCIDR 是 net.ParseCIDR 的包装,返回 *net.IPNet 而不返回 net.IP
func parseCIDR(cidr string) (*net.IPNet, error) {
_, network, err := net.ParseCIDR(cidr)
return network, err
}
// IPInAllowList 检查 IP 是否在白名单中。
//
// 参数:
// - ip: 要检查的 IP 地址
// - allowList: 白名单网络列表
//
// 返回值:
// - bool: IP 在白名单中返回 true
func IPInAllowList(ip net.IP, allowList []net.IPNet) bool {
if len(allowList) == 0 {
return false
}
for _, network := range allowList {
if network.Contains(ip) {
return true
}
}
return false
}