fix: 多次路由取平均,输出方式提取到最外层调用

This commit is contained in:
spiritlhl 2025-08-11 02:15:22 +00:00
parent 6f8f3ed60c
commit 3045cc198a
2 changed files with 70 additions and 48 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net" "net"
"strings" "strings"
"sync"
"github.com/oneclickvirt/backtrace/model" "github.com/oneclickvirt/backtrace/model"
. "github.com/oneclickvirt/defaultset" . "github.com/oneclickvirt/defaultset"
@ -64,22 +65,27 @@ func trace(ch chan Result, i int) {
} }
var allHops [][]*Hop var allHops [][]*Hop
var successfulTraces int var successfulTraces int
// 尝试3次trace var mu sync.Mutex
var wg sync.WaitGroup
// 并发执行3次trace
for attempt := 1; attempt <= 3; attempt++ { for attempt := 1; attempt <= 3; attempt++ {
wg.Add(1)
go func(attemptNum int) {
defer wg.Done()
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attempt, model.Ipv4Names[i], model.Ipv4s[i])) Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv4Names[i], model.Ipv4s[i]))
} }
// 先尝试原始IP地址 // 先尝试原始IP地址
hops, err := Trace(net.ParseIP(model.Ipv4s[i])) hops, err := Trace(net.ParseIP(model.Ipv4s[i]))
if err != nil { if err != nil {
if model.EnableLoger { if model.EnableLoger {
Logger.Warn(fmt.Sprintf("第%d次追踪 %s (%s) 失败: %v", attempt, model.Ipv4Names[i], model.Ipv4s[i], err)) Logger.Warn(fmt.Sprintf("第%d次追踪 %s (%s) 失败: %v", attemptNum, model.Ipv4Names[i], model.Ipv4s[i], err))
} }
// 如果原始IP失败尝试备选IP // 如果原始IP失败尝试备选IP
if tryAltIPs := tryAlternativeIPs(model.Ipv4Names[i], "v4"); len(tryAltIPs) > 0 { if tryAltIPs := tryAlternativeIPs(model.Ipv4Names[i], "v4"); len(tryAltIPs) > 0 {
for _, altIP := range tryAltIPs { for _, altIP := range tryAltIPs {
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attempt, altIP, model.Ipv4Names[i])) Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attemptNum, altIP, model.Ipv4Names[i]))
} }
hops, err = Trace(net.ParseIP(altIP)) hops, err = Trace(net.ParseIP(altIP))
if err == nil && len(hops) > 0 { if err == nil && len(hops) > 0 {
@ -89,13 +95,18 @@ func trace(ch chan Result, i int) {
} }
} }
if err == nil && len(hops) > 0 { if err == nil && len(hops) > 0 {
mu.Lock()
allHops = append(allHops, hops) allHops = append(allHops, hops)
successfulTraces++ successfulTraces++
mu.Unlock()
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次追踪 %s (%s) 成功,获得%d个hop", attempt, model.Ipv4Names[i], model.Ipv4s[i], len(hops))) Logger.Info(fmt.Sprintf("第%d次追踪 %s (%s) 成功,获得%d个hop", attemptNum, model.Ipv4Names[i], model.Ipv4s[i], len(hops)))
} }
} }
}(attempt)
} }
// 等待所有goroutine完成
wg.Wait()
// 如果3次都失败 // 如果3次都失败
if successfulTraces == 0 { if successfulTraces == 0 {
s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], Red("检测不到回程路由节点的IP地址")) s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], Red("检测不到回程路由节点的IP地址"))

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net" "net"
"strings" "strings"
"sync"
"github.com/oneclickvirt/backtrace/model" "github.com/oneclickvirt/backtrace/model"
. "github.com/oneclickvirt/defaultset" . "github.com/oneclickvirt/defaultset"
@ -79,22 +80,27 @@ func traceIPv6(ch chan Result, i int, offset int) {
} }
var allHops [][]*Hop var allHops [][]*Hop
var successfulTraces int var successfulTraces int
// 尝试3次trace var mu sync.Mutex
var wg sync.WaitGroup
// 并发执行3次trace
for attempt := 1; attempt <= 3; attempt++ { for attempt := 1; attempt <= 3; attempt++ {
wg.Add(1)
go func(attemptNum int) {
defer wg.Done()
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attempt, model.Ipv6Names[i], model.Ipv6s[i])) Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv6Names[i], model.Ipv6s[i]))
} }
// 先尝试原始IP地址 // 先尝试原始IP地址
hops, err := Trace(net.ParseIP(model.Ipv6s[i])) hops, err := Trace(net.ParseIP(model.Ipv6s[i]))
if err != nil { if err != nil {
if model.EnableLoger { if model.EnableLoger {
Logger.Warn(fmt.Sprintf("第%d次追踪 %s (%s) 失败: %v", attempt, model.Ipv6Names[i], model.Ipv6s[i], err)) Logger.Warn(fmt.Sprintf("第%d次追踪 %s (%s) 失败: %v", attemptNum, model.Ipv6Names[i], model.Ipv6s[i], err))
} }
// 如果原始IP失败尝试备选IP // 如果原始IP失败尝试备选IP
if tryAltIPs := tryAlternativeIPs(model.Ipv6Names[i], "v6"); len(tryAltIPs) > 0 { if tryAltIPs := tryAlternativeIPs(model.Ipv6Names[i], "v6"); len(tryAltIPs) > 0 {
for _, altIP := range tryAltIPs { for _, altIP := range tryAltIPs {
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attempt, altIP, model.Ipv6Names[i])) Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attemptNum, altIP, model.Ipv6Names[i]))
} }
hops, err = Trace(net.ParseIP(altIP)) hops, err = Trace(net.ParseIP(altIP))
if err == nil && len(hops) > 0 { if err == nil && len(hops) > 0 {
@ -104,13 +110,18 @@ func traceIPv6(ch chan Result, i int, offset int) {
} }
} }
if err == nil && len(hops) > 0 { if err == nil && len(hops) > 0 {
mu.Lock()
allHops = append(allHops, hops) allHops = append(allHops, hops)
successfulTraces++ successfulTraces++
mu.Unlock()
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次追踪 %s (%s) 成功,获得%d个hop", attempt, model.Ipv6Names[i], model.Ipv6s[i], len(hops))) Logger.Info(fmt.Sprintf("第%d次追踪 %s (%s) 成功,获得%d个hop", attemptNum, model.Ipv6Names[i], model.Ipv6s[i], len(hops)))
} }
} }
}(attempt)
} }
// 等待所有goroutine完成
wg.Wait()
// 如果3次都失败 // 如果3次都失败
if successfulTraces == 0 { if successfulTraces == 0 {
s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], Red("检测不到回程路由节点的IP地址")) s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], Red("检测不到回程路由节点的IP地址"))