mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 14:06:44 +08:00
fix: 修复AliveHosts全局变量内存泄漏问题
- 重构CheckLive函数使用局部变量代替全局变量 - 预分配容量避免频繁扩容提升性能 - 移除全局AliveHosts和ExistHosts变量声明 - 更新AliveScanner以使用局部存活主机列表 - 修复多次调用时内存累积问题
This commit is contained in:
parent
78b8ff4f81
commit
b38684bc9e
@ -26,11 +26,12 @@ type AliveScanStrategy struct {
|
||||
|
||||
// AliveStats 存活探测统计信息
|
||||
type AliveStats struct {
|
||||
TotalHosts int // 总主机数
|
||||
AliveHosts int // 存活主机数
|
||||
DeadHosts int // 死亡主机数
|
||||
ScanDuration time.Duration // 扫描耗时
|
||||
SuccessRate float64 // 成功率
|
||||
TotalHosts int // 总主机数
|
||||
AliveHosts int // 存活主机数
|
||||
DeadHosts int // 死亡主机数
|
||||
ScanDuration time.Duration // 扫描耗时
|
||||
SuccessRate float64 // 成功率
|
||||
AliveHostList []string // 存活主机列表
|
||||
}
|
||||
|
||||
// NewAliveScanStrategy 创建新的存活探测扫描策略
|
||||
@ -95,12 +96,6 @@ func (s *AliveScanStrategy) performAliveScan(info common.HostInfo) {
|
||||
common.LogBase(i18n.GetText("scan_alive_multiple_targets", len(hosts), hosts[0]))
|
||||
}
|
||||
|
||||
// 清空之前的存活主机记录
|
||||
AliveHosts = nil
|
||||
for k := range ExistHosts {
|
||||
delete(ExistHosts, k)
|
||||
}
|
||||
|
||||
// 执行存活检测
|
||||
aliveList := CheckLive(hosts, false) // 使用ICMP探测
|
||||
|
||||
@ -108,6 +103,7 @@ func (s *AliveScanStrategy) performAliveScan(info common.HostInfo) {
|
||||
s.stats.AliveHosts = len(aliveList)
|
||||
s.stats.DeadHosts = s.stats.TotalHosts - s.stats.AliveHosts
|
||||
s.stats.ScanDuration = time.Since(s.startTime)
|
||||
s.stats.AliveHostList = aliveList // 存储存活主机列表
|
||||
|
||||
if s.stats.TotalHosts > 0 {
|
||||
s.stats.SuccessRate = float64(s.stats.AliveHosts) / float64(s.stats.TotalHosts) * 100
|
||||
@ -134,7 +130,7 @@ func (s *AliveScanStrategy) outputStats() {
|
||||
common.LogBase("")
|
||||
common.LogBase(i18n.GetText("scan_alive_hosts_list"))
|
||||
|
||||
for i, host := range AliveHosts {
|
||||
for i, host := range s.stats.AliveHostList {
|
||||
common.LogSuccess(fmt.Sprintf(" [%d] %s", i+1, host))
|
||||
}
|
||||
}
|
||||
|
38
Core/ICMP.go
38
Core/ICMP.go
@ -16,25 +16,27 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
AliveHosts []string // 存活主机列表
|
||||
ExistHosts = make(map[string]struct{}) // 已发现主机记录
|
||||
livewg sync.WaitGroup // 存活检测等待组
|
||||
livewg sync.WaitGroup // 存活检测等待组
|
||||
)
|
||||
|
||||
// CheckLive 检测主机存活状态
|
||||
func CheckLive(hostslist []string, Ping bool) []string {
|
||||
// 创建局部存活主机列表,预分配容量避免频繁扩容
|
||||
aliveHosts := make([]string, 0, len(hostslist))
|
||||
existHosts := make(map[string]struct{}, len(hostslist))
|
||||
|
||||
// 创建主机通道
|
||||
chanHosts := make(chan string, len(hostslist))
|
||||
|
||||
// 处理存活主机
|
||||
go handleAliveHosts(chanHosts, hostslist, Ping)
|
||||
go handleAliveHosts(chanHosts, hostslist, Ping, &aliveHosts, existHosts)
|
||||
|
||||
// 根据Ping参数选择检测方式
|
||||
if Ping {
|
||||
// 使用ping方式探测
|
||||
RunPing(hostslist, chanHosts)
|
||||
} else {
|
||||
probeWithICMP(hostslist, chanHosts)
|
||||
probeWithICMP(hostslist, chanHosts, &aliveHosts)
|
||||
}
|
||||
|
||||
// 等待所有检测完成
|
||||
@ -42,9 +44,9 @@ func CheckLive(hostslist []string, Ping bool) []string {
|
||||
close(chanHosts)
|
||||
|
||||
// 输出存活统计信息
|
||||
printAliveStats(hostslist)
|
||||
printAliveStats(aliveHosts, hostslist)
|
||||
|
||||
return AliveHosts
|
||||
return aliveHosts
|
||||
}
|
||||
|
||||
// IsContain 检查切片中是否包含指定元素
|
||||
@ -57,11 +59,11 @@ func IsContain(items []string, item string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func handleAliveHosts(chanHosts chan string, hostslist []string, isPing bool) {
|
||||
func handleAliveHosts(chanHosts chan string, hostslist []string, isPing bool, aliveHosts *[]string, existHosts map[string]struct{}) {
|
||||
for ip := range chanHosts {
|
||||
if _, ok := ExistHosts[ip]; !ok && IsContain(hostslist, ip) {
|
||||
ExistHosts[ip] = struct{}{}
|
||||
AliveHosts = append(AliveHosts, ip)
|
||||
if _, ok := existHosts[ip]; !ok && IsContain(hostslist, ip) {
|
||||
existHosts[ip] = struct{}{}
|
||||
*aliveHosts = append(*aliveHosts, ip)
|
||||
|
||||
// 使用Output系统保存存活主机信息
|
||||
protocol := "ICMP"
|
||||
@ -90,11 +92,11 @@ func handleAliveHosts(chanHosts chan string, hostslist []string, isPing bool) {
|
||||
}
|
||||
|
||||
// probeWithICMP 使用ICMP方式探测
|
||||
func probeWithICMP(hostslist []string, chanHosts chan string) {
|
||||
func probeWithICMP(hostslist []string, chanHosts chan string, aliveHosts *[]string) {
|
||||
// 尝试监听本地ICMP
|
||||
conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err == nil {
|
||||
RunIcmp1(hostslist, conn, chanHosts)
|
||||
RunIcmp1(hostslist, conn, chanHosts, aliveHosts)
|
||||
return
|
||||
}
|
||||
|
||||
@ -134,13 +136,13 @@ func getOptimalTopCount(totalHosts int) int {
|
||||
}
|
||||
|
||||
// printAliveStats 打印存活统计信息
|
||||
func printAliveStats(hostslist []string) {
|
||||
func printAliveStats(aliveHosts []string, hostslist []string) {
|
||||
// 智能计算显示数量
|
||||
topCount := getOptimalTopCount(len(hostslist))
|
||||
|
||||
// 大规模扫描时输出 /16 网段统计
|
||||
if len(hostslist) > 1000 {
|
||||
arrTop, arrLen := ArrayCountValueTop(AliveHosts, topCount, true)
|
||||
arrTop, arrLen := ArrayCountValueTop(aliveHosts, topCount, true)
|
||||
for i := 0; i < len(arrTop); i++ {
|
||||
common.LogInfo(i18n.GetText("subnet_16_alive", arrTop[i], arrLen[i]))
|
||||
}
|
||||
@ -148,7 +150,7 @@ func printAliveStats(hostslist []string) {
|
||||
|
||||
// 输出 /24 网段统计
|
||||
if len(hostslist) > 256 {
|
||||
arrTop, arrLen := ArrayCountValueTop(AliveHosts, topCount, false)
|
||||
arrTop, arrLen := ArrayCountValueTop(aliveHosts, topCount, false)
|
||||
for i := 0; i < len(arrTop); i++ {
|
||||
common.LogInfo(i18n.GetText("subnet_24_alive", arrTop[i], arrLen[i]))
|
||||
}
|
||||
@ -156,7 +158,7 @@ func printAliveStats(hostslist []string) {
|
||||
}
|
||||
|
||||
// RunIcmp1 使用ICMP批量探测主机存活(监听模式)
|
||||
func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string) {
|
||||
func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string, aliveHosts *[]string) {
|
||||
endflag := false
|
||||
|
||||
// 启动监听协程
|
||||
@ -186,7 +188,7 @@ func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string)
|
||||
start := time.Now()
|
||||
for {
|
||||
// 所有主机都已响应则退出
|
||||
if len(AliveHosts) == len(hostslist) {
|
||||
if len(*aliveHosts) == len(hostslist) {
|
||||
break
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user