修复BUG。离线库为国外, API 判断为国内无限循环

This commit is contained in:
aixiao 2025-01-16 14:04:02 +08:00
parent 5a7511427f
commit 612cc35514
4 changed files with 55 additions and 31 deletions

View File

@ -8,3 +8,6 @@ a="'"
eval "CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -a -ldflags ${a}-extldflags \"-static ${libpcap} ${dbus} ${libcap} -lc\"${a}"
if test -f denyip; then
upx -9 denyip
fi

View File

@ -143,5 +143,5 @@ func curl_(IP_ADDR string) (string, error) {
}
*/
return fmt.Sprintf("%s%s\n", HTPP_JSON.Data.Continent, HTPP_JSON.Data.Country), err
return fmt.Sprintf("%s%s", HTPP_JSON.Data.Continent, HTPP_JSON.Data.Country), err
}

BIN
denyip

Binary file not shown.

81
main.go
View File

@ -34,6 +34,9 @@ var (
IpList = list.New() // 存储 IPv4 地址的链表
IpMutex sync.Mutex // 保护 ipList 的互斥锁
ProcessedIPMap = make(map[string]struct{}) // 使用 map 存储已处理的 IP
ProcessedMutex sync.Mutex // 互斥锁保护 ProcessedIPMap
)
// 启动子进程
@ -170,46 +173,64 @@ func runMainProcess() { // 主进程逻辑
// 启动IP地域判断管理
go func() {
for {
IpMutex.Lock() // 锁定互斥锁
if IpList.Len() > 0 { // 链表不为空
e1 := IpList.Front() // 获取链表第一个元素
region, _ := ip2region(e1.Value.(net.IP).String()) // 离线Ip位置库初步判断地域
e1 := IpList.Front() // 获取链表第一个元素
ipStr := e1.Value.(net.IP).String()
region, _ := ip2region(ipStr) // 离线库初步判断地域
if Is_Ip_Ipset(e1.Value.(net.IP).String()) != 0 { // Ip不在 Ipset 集合中
if !strings.Contains(region, "中国") && !strings.Contains(region, "内网") { // 离线库判断不在中国内尝试API判断
if position, err := curl_(e1.Value.(net.IP).String()); err != nil { //API判断地域
log.Printf("获取Ip地域出错: %v", err)
} else {
log.Printf("\033[31m%s %s\033[0m\n", e1.Value.(net.IP).String(), position) // 打印地域
if !strings.Contains(position, "中国") && !strings.Contains(position, "内网") {
AddIPSet(IPSET_NAME, e1.Value.(net.IP).String()) // 添加 Ip 到 ipset 集合
IpList.Remove(e1) // 移除第一个元素
} else { // 这时是国内地址
IpList.Remove(e1) // 移除第一个元素
}
}
} else { // 这时是国内地址
IpList.Remove(e1)
}
} else { // 在 Ipset 集合中
log.Printf("\033[31m %s 在 Ipset 集合中 \033[0m\n", e1.Value.(net.IP).String())
IpList.Remove(e1)
ProcessedMutex.Lock()
_, processed := ProcessedIPMap[ipStr] // 检查是否已处理
ProcessedMutex.Unlock()
if processed { // 如果尚未处理
log.Printf("\033[33m %s 已经标记为国内,跳过!!! \033[0m\n", ipStr)
continue
}
log.Printf(" 当前Ip链表长度:%d, Ipset名:%s, 长:%d\n", IpList.Len(), IPSET_NAME, func() int { // 打印 当前 Ipset 链长度
_len, _err := NumIPSet(IPSET_NAME)
if _err == nil {
return _len
if Is_Ip_Ipset(ipStr) != 0 { // IP 不在 ipset 集合中
if !strings.Contains(region, "中国") && !strings.Contains(region, "内网") { // 离线库判断不在中国内
log.Printf("\033[33m [%s %s] 离线库为国外, 进一步API判断\033[0m\n", ipStr, region)
if position, err := curl_(ipStr); err != nil { // 使用 API 判断地域
log.Printf("获取IP地域出错: %v", err)
} else {
log.Printf("\033[31m [%s %s]\033[0m\n\n", ipStr, position) // 打印地域
if !strings.Contains(position, "中国") && !strings.Contains(position, "内网") { // API 判断为国外
AddIPSet(IPSET_NAME, ipStr) // 添加 IP 到 ipset 集合
} else {
log.Printf("\033[33m %s 离线库为国外, API 判断为国内, 标记为已处理\033[0m\n", ipStr)
// 将 IP 标记为已处理,国内地址
ProcessedMutex.Lock()
ProcessedIPMap[ipStr] = struct{}{}
ProcessedMutex.Unlock()
}
}
}
return 0
}())
time.Sleep(1 * time.Second)
} else { // IP 已在 ipset 集合中
log.Printf("\033[31m %s 在 ipset 集合中 \033[0m\n", ipStr)
}
// 无论是否已处理,都移除该 IP
IpList.Remove(e1)
}
IpMutex.Unlock() // 链表解锁互斥锁
IpMutex.Unlock() // 解锁互斥锁
log.Printf(" 当前Ip链表长度:%d, Ipset名:%s, 长:%d ProcessedIPMap当前长度:%d\n", IpList.Len(), IPSET_NAME, func() int { // 打印 当前 Ipset 链长度
_len, _err := NumIPSet(IPSET_NAME)
if _err == nil {
return _len
}
return 0
}(), len(ProcessedIPMap))
time.Sleep(1 * time.Second) // 防止高频运行
}
}()
// 启动防火墙管理