mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-25 20:51:52 +08:00
fix: align atomic counters on arm
This commit is contained in:
+28
-31
@@ -28,8 +28,8 @@ ProgressManager.go - 固定底部进度条管理器
|
|||||||
type ProgressManager struct {
|
type ProgressManager struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
enabled bool
|
enabled bool
|
||||||
total int64
|
total atomic.Int64
|
||||||
current int64
|
current atomic.Int64
|
||||||
description string
|
description string
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
isActive bool
|
isActive bool
|
||||||
@@ -117,8 +117,8 @@ func (pm *ProgressManager) InitProgress(total int64, description string) {
|
|||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
pm.total = total
|
pm.total.Store(total)
|
||||||
pm.current = 0
|
pm.current.Store(0)
|
||||||
pm.description = description
|
pm.description = description
|
||||||
pm.startTime = time.Now()
|
pm.startTime = time.Now()
|
||||||
pm.isActive = true
|
pm.isActive = true
|
||||||
@@ -144,9 +144,9 @@ func (pm *ProgressManager) UpdateProgress(increment int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 原子累加,避免高并发下的锁竞争
|
// 原子累加,避免高并发下的锁竞争
|
||||||
newCurrent := atomic.AddInt64(&pm.current, increment)
|
newCurrent := pm.current.Add(increment)
|
||||||
if newCurrent > pm.total {
|
if newCurrent > pm.total.Load() {
|
||||||
atomic.StoreInt64(&pm.current, pm.total)
|
pm.current.Store(pm.total.Load())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 节流渲染:距上次渲染不足 50ms 则跳过
|
// 节流渲染:距上次渲染不足 50ms 则跳过
|
||||||
@@ -178,7 +178,7 @@ func (pm *ProgressManager) FinishProgress() {
|
|||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
atomic.StoreInt64(&pm.current, pm.total)
|
pm.current.Store(pm.total.Load())
|
||||||
pm.renderProgress()
|
pm.renderProgress()
|
||||||
|
|
||||||
// 停止活跃指示器
|
// 停止活跃指示器
|
||||||
@@ -219,7 +219,7 @@ func (pm *ProgressManager) generateProgressBar() string {
|
|||||||
// 获取发包统计
|
// 获取发包统计
|
||||||
packetInfo := pm.getPacketInfo()
|
packetInfo := pm.getPacketInfo()
|
||||||
|
|
||||||
if pm.total == 0 {
|
if pm.total.Load() == 0 {
|
||||||
spinner := pm.getActivityIndicator()
|
spinner := pm.getActivityIndicator()
|
||||||
base := fmt.Sprintf("%s %s %s", pm.description, spinner, i18n.GetText("progress_waiting"))
|
base := fmt.Sprintf("%s %s %s", pm.description, spinner, i18n.GetText("progress_waiting"))
|
||||||
if packetInfo != "" {
|
if packetInfo != "" {
|
||||||
@@ -228,9 +228,9 @@ func (pm *ProgressManager) generateProgressBar() string {
|
|||||||
return base
|
return base
|
||||||
}
|
}
|
||||||
|
|
||||||
percentage := float64(atomic.LoadInt64(&pm.current)) / float64(pm.total) * 100
|
percentage := float64(pm.current.Load()) / float64(pm.total.Load()) * 100
|
||||||
elapsed := time.Since(pm.startTime)
|
elapsed := time.Since(pm.startTime)
|
||||||
current := atomic.LoadInt64(&pm.current)
|
current := pm.current.Load()
|
||||||
|
|
||||||
// 计算速度
|
// 计算速度
|
||||||
speed := float64(current) / elapsed.Seconds()
|
speed := float64(current) / elapsed.Seconds()
|
||||||
@@ -241,8 +241,8 @@ func (pm *ProgressManager) generateProgressBar() string {
|
|||||||
|
|
||||||
// 计算预估剩余时间
|
// 计算预估剩余时间
|
||||||
var eta string
|
var eta string
|
||||||
if current > 0 && current < pm.total {
|
if current > 0 && current < pm.total.Load() {
|
||||||
totalTime := elapsed * time.Duration(pm.total) / time.Duration(current)
|
totalTime := elapsed * time.Duration(pm.total.Load()) / time.Duration(current)
|
||||||
remaining := totalTime - elapsed
|
remaining := totalTime - elapsed
|
||||||
if remaining > 0 {
|
if remaining > 0 {
|
||||||
eta = fmt.Sprintf(" ETA:%s", formatDuration(remaining))
|
eta = fmt.Sprintf(" ETA:%s", formatDuration(remaining))
|
||||||
@@ -254,7 +254,7 @@ func (pm *ProgressManager) generateProgressBar() string {
|
|||||||
|
|
||||||
// 计算固定部分的宽度
|
// 计算固定部分的宽度
|
||||||
fixedPart := fmt.Sprintf("%s %s %5.1f%% [] (%d/%d)%s%s %s",
|
fixedPart := fmt.Sprintf("%s %s %5.1f%% [] (%d/%d)%s%s %s",
|
||||||
pm.description, spinner, percentage, current, pm.total, speedStr, eta, packetInfo)
|
pm.description, spinner, percentage, current, pm.total.Load(), speedStr, eta, packetInfo)
|
||||||
fixedWidth := displayWidth(fixedPart)
|
fixedWidth := displayWidth(fixedPart)
|
||||||
|
|
||||||
// 计算进度条槽位可用宽度(预留2字符余量)
|
// 计算进度条槽位可用宽度(预留2字符余量)
|
||||||
@@ -281,7 +281,7 @@ func (pm *ProgressManager) generateProgressBar() string {
|
|||||||
|
|
||||||
// 构建最终进度条
|
// 构建最终进度条
|
||||||
result := fmt.Sprintf("%s %s %5.1f%% %s (%d/%d)%s%s",
|
result := fmt.Sprintf("%s %s %5.1f%% %s (%d/%d)%s%s",
|
||||||
pm.description, spinner, percentage, bar, current, pm.total, speedStr, eta)
|
pm.description, spinner, percentage, bar, current, pm.total.Load(), speedStr, eta)
|
||||||
|
|
||||||
if packetInfo != "" {
|
if packetInfo != "" {
|
||||||
result += " " + packetInfo
|
result += " " + packetInfo
|
||||||
@@ -323,10 +323,10 @@ func (pm *ProgressManager) showCompletionInfo() {
|
|||||||
durationMsg := i18n.GetText("progress_duration")
|
durationMsg := i18n.GetText("progress_duration")
|
||||||
if pm.noColor {
|
if pm.noColor {
|
||||||
fmt.Printf("[%s] %s %d/%d (%s: %s)\n",
|
fmt.Printf("[%s] %s %d/%d (%s: %s)\n",
|
||||||
doneMsg, completionMsg, pm.total, pm.total, durationMsg, formatDuration(elapsed))
|
doneMsg, completionMsg, pm.total.Load(), pm.total.Load(), durationMsg, formatDuration(elapsed))
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%s[%s] %s %d/%d%s %s(%s: %s)%s\n",
|
fmt.Printf("%s[%s] %s %d/%d%s %s(%s: %s)%s\n",
|
||||||
AnsiGreen, doneMsg, completionMsg, pm.total, pm.total, AnsiReset,
|
AnsiGreen, doneMsg, completionMsg, pm.total.Load(), pm.total.Load(), AnsiReset,
|
||||||
AnsiGray, durationMsg, formatDuration(elapsed), AnsiReset)
|
AnsiGray, durationMsg, formatDuration(elapsed), AnsiReset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,10 +478,10 @@ func (pm *ProgressManager) GetPercent() float64 {
|
|||||||
pm.mu.RLock()
|
pm.mu.RLock()
|
||||||
defer pm.mu.RUnlock()
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
if !pm.isActive || pm.total == 0 {
|
if !pm.isActive || pm.total.Load() == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return float64(atomic.LoadInt64(&pm.current)) / float64(pm.total) * 100
|
return float64(pm.current.Load()) / float64(pm.total.Load()) * 100
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -522,8 +522,8 @@ func (pm *ProgressManager) renderProgressUnsafe() {
|
|||||||
|
|
||||||
// 计算当前百分比(避免除零)
|
// 计算当前百分比(避免除零)
|
||||||
currentPercent := 0
|
currentPercent := 0
|
||||||
if pm.total > 0 {
|
if pm.total.Load() > 0 {
|
||||||
currentPercent = int((atomic.LoadInt64(&pm.current) * 100) / pm.total)
|
currentPercent = int((pm.current.Load() * 100) / pm.total.Load())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只在百分比变化时更新,减少不必要的渲染
|
// 只在百分比变化时更新,减少不必要的渲染
|
||||||
@@ -642,8 +642,8 @@ ConcurrencyMonitor - 并发监控器
|
|||||||
// ConcurrencyMonitor 并发监控器
|
// ConcurrencyMonitor 并发监控器
|
||||||
type ConcurrencyMonitor struct {
|
type ConcurrencyMonitor struct {
|
||||||
// 主扫描器层级
|
// 主扫描器层级
|
||||||
activePluginTasks int64 // 当前活跃的插件任务数
|
activePluginTasks atomic.Int64 // 当前活跃的插件任务数
|
||||||
totalPluginTasks int64 // 总插件任务数
|
totalPluginTasks atomic.Int64 // 总插件任务数
|
||||||
|
|
||||||
// 插件内连接层级已移除 - 原代码为死代码,无任何调用者
|
// 插件内连接层级已移除 - 原代码为死代码,无任何调用者
|
||||||
}
|
}
|
||||||
@@ -658,10 +658,7 @@ var (
|
|||||||
// GetConcurrencyMonitor 获取全局并发监控器
|
// GetConcurrencyMonitor 获取全局并发监控器
|
||||||
func GetConcurrencyMonitor() *ConcurrencyMonitor {
|
func GetConcurrencyMonitor() *ConcurrencyMonitor {
|
||||||
concurrencyMutex.Do(func() {
|
concurrencyMutex.Do(func() {
|
||||||
globalConcurrencyMonitor = &ConcurrencyMonitor{
|
globalConcurrencyMonitor = &ConcurrencyMonitor{}
|
||||||
activePluginTasks: 0,
|
|
||||||
totalPluginTasks: 0,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return globalConcurrencyMonitor
|
return globalConcurrencyMonitor
|
||||||
}
|
}
|
||||||
@@ -672,18 +669,18 @@ func GetConcurrencyMonitor() *ConcurrencyMonitor {
|
|||||||
|
|
||||||
// StartPluginTask 开始插件任务
|
// StartPluginTask 开始插件任务
|
||||||
func (m *ConcurrencyMonitor) StartPluginTask() {
|
func (m *ConcurrencyMonitor) StartPluginTask() {
|
||||||
atomic.AddInt64(&m.activePluginTasks, 1)
|
m.activePluginTasks.Add(1)
|
||||||
atomic.AddInt64(&m.totalPluginTasks, 1)
|
m.totalPluginTasks.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinishPluginTask 完成插件任务
|
// FinishPluginTask 完成插件任务
|
||||||
func (m *ConcurrencyMonitor) FinishPluginTask() {
|
func (m *ConcurrencyMonitor) FinishPluginTask() {
|
||||||
atomic.AddInt64(&m.activePluginTasks, -1)
|
m.activePluginTasks.Add(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPluginTaskStats 获取插件任务统计
|
// GetPluginTaskStats 获取插件任务统计
|
||||||
func (m *ConcurrencyMonitor) GetPluginTaskStats() (active int64, total int64) {
|
func (m *ConcurrencyMonitor) GetPluginTaskStats() (active int64, total int64) {
|
||||||
return atomic.LoadInt64(&m.activePluginTasks), atomic.LoadInt64(&m.totalPluginTasks)
|
return m.activePluginTasks.Load(), m.totalPluginTasks.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,33 +23,27 @@ func (h *httpDialer) Dial(network, address string) (net.Conn, error) {
|
|||||||
|
|
||||||
func (h *httpDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
func (h *httpDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
atomic.AddInt64(&h.stats.TotalConnections, 1)
|
h.stats.addTotal(1)
|
||||||
|
|
||||||
// 连接到HTTP代理服务器
|
// 连接到HTTP代理服务器
|
||||||
proxyConn, err := h.baseDial.DialContext(ctx, NetworkTCP, h.config.Address)
|
proxyConn, err := h.baseDial.DialContext(ctx, NetworkTCP, h.config.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
atomic.AddInt64(&h.stats.FailedConnections, 1)
|
h.stats.addFailed(1)
|
||||||
h.stats.mu.Lock()
|
h.stats.setLastError(err.Error())
|
||||||
h.stats.LastError = err.Error()
|
|
||||||
h.stats.mu.Unlock()
|
|
||||||
return nil, NewProxyError(ErrTypeConnection, ErrMsgHTTPConnFailed, ErrCodeHTTPConnFailed, err)
|
return nil, NewProxyError(ErrTypeConnection, ErrMsgHTTPConnFailed, ErrCodeHTTPConnFailed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送CONNECT请求
|
// 发送CONNECT请求
|
||||||
if err := h.sendConnectRequest(proxyConn, address); err != nil {
|
if err := h.sendConnectRequest(proxyConn, address); err != nil {
|
||||||
_ = proxyConn.Close() // 错误处理路径,Close错误可忽略
|
_ = proxyConn.Close() // 错误处理路径,Close错误可忽略
|
||||||
atomic.AddInt64(&h.stats.FailedConnections, 1)
|
h.stats.addFailed(1)
|
||||||
h.stats.mu.Lock()
|
h.stats.setLastError(err.Error())
|
||||||
h.stats.LastError = err.Error()
|
|
||||||
h.stats.mu.Unlock()
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
h.stats.mu.Lock()
|
h.stats.setLastConnectTime(start)
|
||||||
h.stats.LastConnectTime = start
|
h.stats.addActive(1)
|
||||||
h.stats.mu.Unlock()
|
|
||||||
atomic.AddInt64(&h.stats.ActiveConnections, 1)
|
|
||||||
h.updateAverageConnectTime(duration)
|
h.updateAverageConnectTime(duration)
|
||||||
|
|
||||||
return &trackedConn{
|
return &trackedConn{
|
||||||
|
|||||||
+13
-36
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
@@ -127,19 +126,7 @@ func (m *manager) Stats() *ProxyStats {
|
|||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
m.stats.mu.Lock()
|
return m.stats.snapshot()
|
||||||
defer m.stats.mu.Unlock()
|
|
||||||
|
|
||||||
return &ProxyStats{
|
|
||||||
TotalConnections: atomic.LoadInt64(&m.stats.TotalConnections),
|
|
||||||
ActiveConnections: atomic.LoadInt64(&m.stats.ActiveConnections),
|
|
||||||
FailedConnections: atomic.LoadInt64(&m.stats.FailedConnections),
|
|
||||||
AverageConnectTime: m.stats.AverageConnectTime,
|
|
||||||
LastConnectTime: m.stats.LastConnectTime,
|
|
||||||
LastError: m.stats.LastError,
|
|
||||||
ProxyType: m.stats.ProxyType,
|
|
||||||
ProxyAddress: m.stats.ProxyAddress,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createDirectDialer 创建直连拨号器
|
// createDirectDialer 创建直连拨号器
|
||||||
@@ -246,7 +233,7 @@ func (d *directDialer) Dial(network, address string) (net.Conn, error) {
|
|||||||
|
|
||||||
func (d *directDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
func (d *directDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
atomic.AddInt64(&d.stats.TotalConnections, 1)
|
d.stats.addTotal(1)
|
||||||
|
|
||||||
dialer := &net.Dialer{
|
dialer := &net.Dialer{
|
||||||
Timeout: d.timeout,
|
Timeout: d.timeout,
|
||||||
@@ -263,19 +250,15 @@ func (d *directDialer) DialContext(ctx context.Context, network, address string)
|
|||||||
|
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
|
|
||||||
d.stats.mu.Lock()
|
d.stats.setLastConnectTime(start)
|
||||||
d.stats.LastConnectTime = start
|
|
||||||
d.stats.mu.Unlock()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
atomic.AddInt64(&d.stats.FailedConnections, 1)
|
d.stats.addFailed(1)
|
||||||
d.stats.mu.Lock()
|
d.stats.setLastError(err.Error())
|
||||||
d.stats.LastError = err.Error()
|
|
||||||
d.stats.mu.Unlock()
|
|
||||||
return nil, NewProxyError(ErrTypeConnection, ErrMsgDirectConnFailed, ErrCodeDirectConnFailed, err)
|
return nil, NewProxyError(ErrTypeConnection, ErrMsgDirectConnFailed, ErrCodeDirectConnFailed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic.AddInt64(&d.stats.ActiveConnections, 1)
|
d.stats.addActive(1)
|
||||||
d.updateAverageConnectTime(duration)
|
d.updateAverageConnectTime(duration)
|
||||||
|
|
||||||
return &trackedConn{
|
return &trackedConn{
|
||||||
@@ -297,7 +280,7 @@ func (s *socks5Dialer) Dial(network, address string) (net.Conn, error) {
|
|||||||
|
|
||||||
func (s *socks5Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
func (s *socks5Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
atomic.AddInt64(&s.stats.TotalConnections, 1)
|
s.stats.addTotal(1)
|
||||||
|
|
||||||
// 创建一个带超时的上下文
|
// 创建一个带超时的上下文
|
||||||
dialCtx, cancel := context.WithTimeout(ctx, s.config.Timeout)
|
dialCtx, cancel := context.WithTimeout(ctx, s.config.Timeout)
|
||||||
@@ -325,27 +308,21 @@ func (s *socks5Dialer) DialContext(ctx context.Context, network, address string)
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case <-dialCtx.Done():
|
case <-dialCtx.Done():
|
||||||
atomic.AddInt64(&s.stats.FailedConnections, 1)
|
s.stats.addFailed(1)
|
||||||
s.stats.mu.Lock()
|
s.stats.setLastError(dialCtx.Err().Error())
|
||||||
s.stats.LastError = dialCtx.Err().Error()
|
|
||||||
s.stats.mu.Unlock()
|
|
||||||
return nil, NewProxyError(ErrTypeTimeout, ErrMsgSOCKS5ConnTimeout, ErrCodeSOCKS5ConnTimeout, dialCtx.Err())
|
return nil, NewProxyError(ErrTypeTimeout, ErrMsgSOCKS5ConnTimeout, ErrCodeSOCKS5ConnTimeout, dialCtx.Err())
|
||||||
case result := <-connChan:
|
case result := <-connChan:
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
|
|
||||||
s.stats.mu.Lock()
|
s.stats.setLastConnectTime(start)
|
||||||
s.stats.LastConnectTime = start
|
|
||||||
s.stats.mu.Unlock()
|
|
||||||
|
|
||||||
if result.err != nil {
|
if result.err != nil {
|
||||||
atomic.AddInt64(&s.stats.FailedConnections, 1)
|
s.stats.addFailed(1)
|
||||||
s.stats.mu.Lock()
|
s.stats.setLastError(result.err.Error())
|
||||||
s.stats.LastError = result.err.Error()
|
|
||||||
s.stats.mu.Unlock()
|
|
||||||
return nil, NewProxyError(ErrTypeConnection, ErrMsgSOCKS5ConnFailed, ErrCodeSOCKS5ConnFailed, result.err)
|
return nil, NewProxyError(ErrTypeConnection, ErrMsgSOCKS5ConnFailed, ErrCodeSOCKS5ConnFailed, result.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic.AddInt64(&s.stats.ActiveConnections, 1)
|
s.stats.addActive(1)
|
||||||
s.updateAverageConnectTime(duration)
|
s.updateAverageConnectTime(duration)
|
||||||
|
|
||||||
return &trackedConn{
|
return &trackedConn{
|
||||||
|
|||||||
@@ -49,10 +49,8 @@ func (t *tlsDialerWrapper) DialTLSContext(ctx context.Context, network, address
|
|||||||
// 进行TLS握手
|
// 进行TLS握手
|
||||||
if err := tlsConn.Handshake(); err != nil {
|
if err := tlsConn.Handshake(); err != nil {
|
||||||
_ = tcpConn.Close() // TLS握手失败,Close错误可忽略
|
_ = tcpConn.Close() // TLS握手失败,Close错误可忽略
|
||||||
atomic.AddInt64(&t.stats.FailedConnections, 1)
|
t.stats.addFailed(1)
|
||||||
t.stats.mu.Lock()
|
t.stats.setLastError(err.Error())
|
||||||
t.stats.LastError = err.Error()
|
|
||||||
t.stats.mu.Unlock()
|
|
||||||
return nil, NewProxyError(ErrTypeConnection, ErrMsgTLSHandshakeFailed, ErrCodeTLSHandshakeFailed, err)
|
return nil, NewProxyError(ErrTypeConnection, ErrMsgTLSHandshakeFailed, ErrCodeTLSHandshakeFailed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,16 +82,16 @@ func (t *tlsDialerWrapper) updateAverageConnectTime(duration time.Duration) {
|
|||||||
|
|
||||||
// trackedConn 带统计的连接
|
// trackedConn 带统计的连接
|
||||||
type trackedConn struct {
|
type trackedConn struct {
|
||||||
|
bytesSent atomic.Int64
|
||||||
|
bytesRecv atomic.Int64
|
||||||
net.Conn
|
net.Conn
|
||||||
stats *ProxyStats
|
stats *ProxyStats
|
||||||
bytesSent int64
|
|
||||||
bytesRecv int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *trackedConn) Read(b []byte) (n int, err error) {
|
func (tc *trackedConn) Read(b []byte) (n int, err error) {
|
||||||
n, err = tc.Conn.Read(b)
|
n, err = tc.Conn.Read(b)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
atomic.AddInt64(&tc.bytesRecv, int64(n))
|
tc.bytesRecv.Add(int64(n))
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
@@ -101,13 +99,13 @@ func (tc *trackedConn) Read(b []byte) (n int, err error) {
|
|||||||
func (tc *trackedConn) Write(b []byte) (n int, err error) {
|
func (tc *trackedConn) Write(b []byte) (n int, err error) {
|
||||||
n, err = tc.Conn.Write(b)
|
n, err = tc.Conn.Write(b)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
atomic.AddInt64(&tc.bytesSent, int64(n))
|
tc.bytesSent.Add(int64(n))
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *trackedConn) Close() error {
|
func (tc *trackedConn) Close() error {
|
||||||
atomic.AddInt64(&tc.stats.ActiveConnections, -1)
|
tc.stats.addActive(-1)
|
||||||
return tc.Conn.Close()
|
return tc.Conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+49
-3
@@ -96,9 +96,9 @@ type ProxyManager interface {
|
|||||||
//
|
//
|
||||||
//nolint:revive // 保持与现有代码的向后兼容性
|
//nolint:revive // 保持与现有代码的向后兼容性
|
||||||
type ProxyStats struct {
|
type ProxyStats struct {
|
||||||
TotalConnections int64 `json:"total_connections"`
|
TotalConnections int64 `json:"total_connections"`
|
||||||
ActiveConnections int64 `json:"active_connections"`
|
ActiveConnections int64 `json:"active_connections"`
|
||||||
FailedConnections int64 `json:"failed_connections"`
|
FailedConnections int64 `json:"failed_connections"`
|
||||||
mu sync.Mutex `json:"-"`
|
mu sync.Mutex `json:"-"`
|
||||||
AverageConnectTime time.Duration `json:"average_connect_time"`
|
AverageConnectTime time.Duration `json:"average_connect_time"`
|
||||||
LastConnectTime time.Time `json:"last_connect_time"`
|
LastConnectTime time.Time `json:"last_connect_time"`
|
||||||
@@ -107,6 +107,52 @@ type ProxyStats struct {
|
|||||||
ProxyAddress string `json:"proxy_address"`
|
ProxyAddress string `json:"proxy_address"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ProxyStats) addTotal(delta int64) {
|
||||||
|
s.mu.Lock()
|
||||||
|
s.TotalConnections += delta
|
||||||
|
s.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProxyStats) addActive(delta int64) {
|
||||||
|
s.mu.Lock()
|
||||||
|
s.ActiveConnections += delta
|
||||||
|
s.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProxyStats) addFailed(delta int64) {
|
||||||
|
s.mu.Lock()
|
||||||
|
s.FailedConnections += delta
|
||||||
|
s.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProxyStats) setLastConnectTime(t time.Time) {
|
||||||
|
s.mu.Lock()
|
||||||
|
s.LastConnectTime = t
|
||||||
|
s.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProxyStats) setLastError(err string) {
|
||||||
|
s.mu.Lock()
|
||||||
|
s.LastError = err
|
||||||
|
s.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProxyStats) snapshot() *ProxyStats {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
return &ProxyStats{
|
||||||
|
TotalConnections: s.TotalConnections,
|
||||||
|
ActiveConnections: s.ActiveConnections,
|
||||||
|
FailedConnections: s.FailedConnections,
|
||||||
|
AverageConnectTime: s.AverageConnectTime,
|
||||||
|
LastConnectTime: s.LastConnectTime,
|
||||||
|
LastError: s.LastError,
|
||||||
|
ProxyType: s.ProxyType,
|
||||||
|
ProxyAddress: s.ProxyAddress,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ProxyError 代理错误类型
|
// ProxyError 代理错误类型
|
||||||
//
|
//
|
||||||
//nolint:revive // 保持与现有代码的向后兼容性
|
//nolint:revive // 保持与现有代码的向后兼容性
|
||||||
|
|||||||
+49
-49
@@ -23,17 +23,17 @@ state.go - 运行时状态管理
|
|||||||
// State 扫描器运行时状态 - 线程安全
|
// State 扫描器运行时状态 - 线程安全
|
||||||
type State struct {
|
type State struct {
|
||||||
// 计数器 - 原子操作
|
// 计数器 - 原子操作
|
||||||
packetCount int64
|
packetCount atomic.Int64
|
||||||
tcpPacketCount int64
|
tcpPacketCount atomic.Int64
|
||||||
tcpSuccessPacketCount int64
|
tcpSuccessPacketCount atomic.Int64
|
||||||
tcpFailedPacketCount int64
|
tcpFailedPacketCount atomic.Int64
|
||||||
udpPacketCount int64
|
udpPacketCount atomic.Int64
|
||||||
httpPacketCount int64
|
httpPacketCount atomic.Int64
|
||||||
resourceExhaustedCount int64
|
resourceExhaustedCount atomic.Int64
|
||||||
|
|
||||||
// 任务计数
|
// 任务计数
|
||||||
end int64
|
end atomic.Int64
|
||||||
num int64
|
num atomic.Int64
|
||||||
|
|
||||||
// 时间
|
// 时间
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
@@ -71,38 +71,38 @@ func NewState() *State {
|
|||||||
|
|
||||||
// IncrementPacketCount 增加总包计数
|
// IncrementPacketCount 增加总包计数
|
||||||
func (s *State) IncrementPacketCount() int64 {
|
func (s *State) IncrementPacketCount() int64 {
|
||||||
return atomic.AddInt64(&s.packetCount, 1)
|
return s.packetCount.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrementTCPSuccessPacketCount 增加TCP成功连接包计数
|
// IncrementTCPSuccessPacketCount 增加TCP成功连接包计数
|
||||||
func (s *State) IncrementTCPSuccessPacketCount() int64 {
|
func (s *State) IncrementTCPSuccessPacketCount() int64 {
|
||||||
atomic.AddInt64(&s.tcpSuccessPacketCount, 1)
|
s.tcpSuccessPacketCount.Add(1)
|
||||||
atomic.AddInt64(&s.tcpPacketCount, 1)
|
s.tcpPacketCount.Add(1)
|
||||||
return atomic.AddInt64(&s.packetCount, 1)
|
return s.packetCount.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrementTCPFailedPacketCount 增加TCP失败连接包计数
|
// IncrementTCPFailedPacketCount 增加TCP失败连接包计数
|
||||||
func (s *State) IncrementTCPFailedPacketCount() int64 {
|
func (s *State) IncrementTCPFailedPacketCount() int64 {
|
||||||
atomic.AddInt64(&s.tcpFailedPacketCount, 1)
|
s.tcpFailedPacketCount.Add(1)
|
||||||
atomic.AddInt64(&s.tcpPacketCount, 1)
|
s.tcpPacketCount.Add(1)
|
||||||
return atomic.AddInt64(&s.packetCount, 1)
|
return s.packetCount.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrementUDPPacketCount 增加UDP包计数
|
// IncrementUDPPacketCount 增加UDP包计数
|
||||||
func (s *State) IncrementUDPPacketCount() int64 {
|
func (s *State) IncrementUDPPacketCount() int64 {
|
||||||
atomic.AddInt64(&s.udpPacketCount, 1)
|
s.udpPacketCount.Add(1)
|
||||||
return atomic.AddInt64(&s.packetCount, 1)
|
return s.packetCount.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrementHTTPPacketCount 增加HTTP包计数
|
// IncrementHTTPPacketCount 增加HTTP包计数
|
||||||
func (s *State) IncrementHTTPPacketCount() int64 {
|
func (s *State) IncrementHTTPPacketCount() int64 {
|
||||||
atomic.AddInt64(&s.httpPacketCount, 1)
|
s.httpPacketCount.Add(1)
|
||||||
return atomic.AddInt64(&s.packetCount, 1)
|
return s.packetCount.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrementResourceExhaustedCount 增加资源耗尽错误计数
|
// IncrementResourceExhaustedCount 增加资源耗尽错误计数
|
||||||
func (s *State) IncrementResourceExhaustedCount() {
|
func (s *State) IncrementResourceExhaustedCount() {
|
||||||
atomic.AddInt64(&s.resourceExhaustedCount, 1)
|
s.resourceExhaustedCount.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -111,48 +111,48 @@ func (s *State) IncrementResourceExhaustedCount() {
|
|||||||
|
|
||||||
// GetPacketCount 获取总包计数
|
// GetPacketCount 获取总包计数
|
||||||
func (s *State) GetPacketCount() int64 {
|
func (s *State) GetPacketCount() int64 {
|
||||||
return atomic.LoadInt64(&s.packetCount)
|
return s.packetCount.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTCPPacketCount 获取TCP包计数
|
// GetTCPPacketCount 获取TCP包计数
|
||||||
func (s *State) GetTCPPacketCount() int64 {
|
func (s *State) GetTCPPacketCount() int64 {
|
||||||
return atomic.LoadInt64(&s.tcpPacketCount)
|
return s.tcpPacketCount.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTCPSuccessPacketCount 获取TCP成功连接包计数
|
// GetTCPSuccessPacketCount 获取TCP成功连接包计数
|
||||||
func (s *State) GetTCPSuccessPacketCount() int64 {
|
func (s *State) GetTCPSuccessPacketCount() int64 {
|
||||||
return atomic.LoadInt64(&s.tcpSuccessPacketCount)
|
return s.tcpSuccessPacketCount.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTCPFailedPacketCount 获取TCP失败连接包计数
|
// GetTCPFailedPacketCount 获取TCP失败连接包计数
|
||||||
func (s *State) GetTCPFailedPacketCount() int64 {
|
func (s *State) GetTCPFailedPacketCount() int64 {
|
||||||
return atomic.LoadInt64(&s.tcpFailedPacketCount)
|
return s.tcpFailedPacketCount.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUDPPacketCount 获取UDP包计数
|
// GetUDPPacketCount 获取UDP包计数
|
||||||
func (s *State) GetUDPPacketCount() int64 {
|
func (s *State) GetUDPPacketCount() int64 {
|
||||||
return atomic.LoadInt64(&s.udpPacketCount)
|
return s.udpPacketCount.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHTTPPacketCount 获取HTTP包计数
|
// GetHTTPPacketCount 获取HTTP包计数
|
||||||
func (s *State) GetHTTPPacketCount() int64 {
|
func (s *State) GetHTTPPacketCount() int64 {
|
||||||
return atomic.LoadInt64(&s.httpPacketCount)
|
return s.httpPacketCount.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetResourceExhaustedCount 获取资源耗尽错误计数
|
// GetResourceExhaustedCount 获取资源耗尽错误计数
|
||||||
func (s *State) GetResourceExhaustedCount() int64 {
|
func (s *State) GetResourceExhaustedCount() int64 {
|
||||||
return atomic.LoadInt64(&s.resourceExhaustedCount)
|
return s.resourceExhaustedCount.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetPacketCounters 重置所有包计数器
|
// ResetPacketCounters 重置所有包计数器
|
||||||
func (s *State) ResetPacketCounters() {
|
func (s *State) ResetPacketCounters() {
|
||||||
atomic.StoreInt64(&s.packetCount, 0)
|
s.packetCount.Store(0)
|
||||||
atomic.StoreInt64(&s.tcpPacketCount, 0)
|
s.tcpPacketCount.Store(0)
|
||||||
atomic.StoreInt64(&s.tcpSuccessPacketCount, 0)
|
s.tcpSuccessPacketCount.Store(0)
|
||||||
atomic.StoreInt64(&s.tcpFailedPacketCount, 0)
|
s.tcpFailedPacketCount.Store(0)
|
||||||
atomic.StoreInt64(&s.udpPacketCount, 0)
|
s.udpPacketCount.Store(0)
|
||||||
atomic.StoreInt64(&s.httpPacketCount, 0)
|
s.httpPacketCount.Store(0)
|
||||||
atomic.StoreInt64(&s.resourceExhaustedCount, 0)
|
s.resourceExhaustedCount.Store(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -161,32 +161,32 @@ func (s *State) ResetPacketCounters() {
|
|||||||
|
|
||||||
// GetEnd 获取结束计数
|
// GetEnd 获取结束计数
|
||||||
func (s *State) GetEnd() int64 {
|
func (s *State) GetEnd() int64 {
|
||||||
return atomic.LoadInt64(&s.end)
|
return s.end.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNum 获取数量计数
|
// GetNum 获取数量计数
|
||||||
func (s *State) GetNum() int64 {
|
func (s *State) GetNum() int64 {
|
||||||
return atomic.LoadInt64(&s.num)
|
return s.num.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrementEnd 增加结束计数
|
// IncrementEnd 增加结束计数
|
||||||
func (s *State) IncrementEnd() int64 {
|
func (s *State) IncrementEnd() int64 {
|
||||||
return atomic.AddInt64(&s.end, 1)
|
return s.end.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IncrementNum 增加数量计数
|
// IncrementNum 增加数量计数
|
||||||
func (s *State) IncrementNum() int64 {
|
func (s *State) IncrementNum() int64 {
|
||||||
return atomic.AddInt64(&s.num, 1)
|
return s.num.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEnd 设置结束计数
|
// SetEnd 设置结束计数
|
||||||
func (s *State) SetEnd(val int64) {
|
func (s *State) SetEnd(val int64) {
|
||||||
atomic.StoreInt64(&s.end, val)
|
s.end.Store(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNum 设置数量计数
|
// SetNum 设置数量计数
|
||||||
func (s *State) SetNum(val int64) {
|
func (s *State) SetNum(val int64) {
|
||||||
atomic.StoreInt64(&s.num, val)
|
s.num.Store(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -271,10 +271,10 @@ type PerfStatsData struct {
|
|||||||
func (s *State) GetPerfStats() PerfStatsData {
|
func (s *State) GetPerfStats() PerfStatsData {
|
||||||
duration := time.Since(s.startTime)
|
duration := time.Since(s.startTime)
|
||||||
durationMs := duration.Milliseconds()
|
durationMs := duration.Milliseconds()
|
||||||
totalPackets := atomic.LoadInt64(&s.packetCount)
|
totalPackets := s.packetCount.Load()
|
||||||
tcpSuccess := atomic.LoadInt64(&s.tcpSuccessPacketCount)
|
tcpSuccess := s.tcpSuccessPacketCount.Load()
|
||||||
tcpFailed := atomic.LoadInt64(&s.tcpFailedPacketCount)
|
tcpFailed := s.tcpFailedPacketCount.Load()
|
||||||
tcpTotal := atomic.LoadInt64(&s.tcpPacketCount)
|
tcpTotal := s.tcpPacketCount.Load()
|
||||||
|
|
||||||
var pps float64
|
var pps float64
|
||||||
if durationMs > 0 {
|
if durationMs > 0 {
|
||||||
@@ -291,13 +291,13 @@ func (s *State) GetPerfStats() PerfStatsData {
|
|||||||
TCPPackets: tcpTotal,
|
TCPPackets: tcpTotal,
|
||||||
TCPSuccess: tcpSuccess,
|
TCPSuccess: tcpSuccess,
|
||||||
TCPFailed: tcpFailed,
|
TCPFailed: tcpFailed,
|
||||||
UDPPackets: atomic.LoadInt64(&s.udpPacketCount),
|
UDPPackets: s.udpPacketCount.Load(),
|
||||||
HTTPPackets: atomic.LoadInt64(&s.httpPacketCount),
|
HTTPPackets: s.httpPacketCount.Load(),
|
||||||
ResourceExhausted: atomic.LoadInt64(&s.resourceExhaustedCount),
|
ResourceExhausted: s.resourceExhaustedCount.Load(),
|
||||||
ScanDurationMs: durationMs,
|
ScanDurationMs: durationMs,
|
||||||
PacketsPerSecond: pps,
|
PacketsPerSecond: pps,
|
||||||
SuccessRate: successRate,
|
SuccessRate: successRate,
|
||||||
TargetsScanned: atomic.LoadInt64(&s.num),
|
TargetsScanned: s.num.Load(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ type AdaptivePool struct {
|
|||||||
|
|
||||||
// 监控参数
|
// 监控参数
|
||||||
checkInterval time.Duration
|
checkInterval time.Duration
|
||||||
lastCheckNano int64 // 原子, UnixNano
|
lastCheckNano atomic.Int64 // UnixNano
|
||||||
lastExhaustedCount int64
|
lastExhaustedCount int64
|
||||||
lastPacketCount int64
|
lastPacketCount int64
|
||||||
|
|
||||||
@@ -70,12 +70,12 @@ func (ap *AdaptivePool) Invoke(task interface{}) error {
|
|||||||
// maybeAdjust 检查并可能调整线程池大小
|
// maybeAdjust 检查并可能调整线程池大小
|
||||||
// 使用原子 CAS 进行时间检查,99%+ 的调用零锁开销
|
// 使用原子 CAS 进行时间检查,99%+ 的调用零锁开销
|
||||||
func (ap *AdaptivePool) maybeAdjust() {
|
func (ap *AdaptivePool) maybeAdjust() {
|
||||||
lastCheck := atomic.LoadInt64(&ap.lastCheckNano)
|
lastCheck := ap.lastCheckNano.Load()
|
||||||
now := time.Now().UnixNano()
|
now := time.Now().UnixNano()
|
||||||
if now-lastCheck < int64(ap.checkInterval) {
|
if now-lastCheck < int64(ap.checkInterval) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !atomic.CompareAndSwapInt64(&ap.lastCheckNano, lastCheck, now) {
|
if !ap.lastCheckNano.CompareAndSwap(lastCheck, now) {
|
||||||
return // 其他 goroutine 已在检查
|
return // 其他 goroutine 已在检查
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -210,7 +210,7 @@ func EnhancedPortScan(ctx context.Context, hosts []string, ports string, timeout
|
|||||||
// 初始化并发控制
|
// 初始化并发控制
|
||||||
to := time.Duration(timeout) * time.Second
|
to := time.Duration(timeout) * time.Second
|
||||||
adaptiveTO := NewAdaptiveTimeout(to)
|
adaptiveTO := NewAdaptiveTimeout(to)
|
||||||
var count int64
|
var count atomic.Int64
|
||||||
collector := newResultCollector(stream)
|
collector := newResultCollector(stream)
|
||||||
failedCollector := &failedPortCollector{}
|
failedCollector := &failedPortCollector{}
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
@@ -258,7 +258,7 @@ func EnhancedPortScan(ctx context.Context, hosts []string, ports string, timeout
|
|||||||
common.FinishProgressBar()
|
common.FinishProgressBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
session.LogInfo(i18n.Tr("port_scan_complete", count))
|
session.LogInfo(i18n.Tr("port_scan_complete", count.Load()))
|
||||||
|
|
||||||
// 检查扫描失败率,如果过高则警告用户
|
// 检查扫描失败率,如果过高则警告用户
|
||||||
resourceErrors := state.GetResourceExhaustedCount()
|
resourceErrors := state.GetResourceExhaustedCount()
|
||||||
@@ -453,7 +453,7 @@ func buildServiceLogMessage(addr string, serviceInfo *ServiceInfo, isWeb bool) s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scanSinglePort 扫描单个端口并进行服务识别(重构后的简洁版本)
|
// scanSinglePort 扫描单个端口并进行服务识别(重构后的简洁版本)
|
||||||
func scanSinglePort(ctx context.Context, host string, port int, addr string, adaptiveTO *AdaptiveTimeout, count *int64, collector *resultCollector, failedCollector *failedPortCollector, session *common.ScanSession) {
|
func scanSinglePort(ctx context.Context, host string, port int, addr string, adaptiveTO *AdaptiveTimeout, count *atomic.Int64, collector *resultCollector, failedCollector *failedPortCollector, session *common.ScanSession) {
|
||||||
config := session.Config
|
config := session.Config
|
||||||
timeout := adaptiveTO.Timeout()
|
timeout := adaptiveTO.Timeout()
|
||||||
// 步骤1:建立连接
|
// 步骤1:建立连接
|
||||||
@@ -486,7 +486,7 @@ func scanSinglePort(ctx context.Context, host string, port int, addr string, ada
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 步骤2:记录开放端口
|
// 步骤2:记录开放端口
|
||||||
atomic.AddInt64(count, 1)
|
count.Add(1)
|
||||||
collector.Add(addr)
|
collector.Add(addr)
|
||||||
saveOpenPort(session, host, port)
|
saveOpenPort(session, host, port)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user