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,38 +65,48 @@ 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++ {
if model.EnableLoger { wg.Add(1)
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attempt, model.Ipv4Names[i], model.Ipv4s[i])) go func(attemptNum int) {
} defer wg.Done()
// 先尝试原始IP地址
hops, err := Trace(net.ParseIP(model.Ipv4s[i]))
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.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv4Names[i], model.Ipv4s[i]))
} }
// 如果原始IP失败尝试备选IP // 先尝试原始IP地址
if tryAltIPs := tryAlternativeIPs(model.Ipv4Names[i], "v4"); len(tryAltIPs) > 0 { hops, err := Trace(net.ParseIP(model.Ipv4s[i]))
for _, altIP := range tryAltIPs { if err != nil {
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attempt, altIP, model.Ipv4Names[i])) Logger.Warn(fmt.Sprintf("第%d次追踪 %s (%s) 失败: %v", attemptNum, model.Ipv4Names[i], model.Ipv4s[i], err))
} }
hops, err = Trace(net.ParseIP(altIP)) // 如果原始IP失败尝试备选IP
if err == nil && len(hops) > 0 { if tryAltIPs := tryAlternativeIPs(model.Ipv4Names[i], "v4"); len(tryAltIPs) > 0 {
break // 成功找到可用IP for _, altIP := range tryAltIPs {
if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attemptNum, altIP, model.Ipv4Names[i]))
}
hops, err = Trace(net.ParseIP(altIP))
if err == nil && len(hops) > 0 {
break // 成功找到可用IP
}
} }
} }
} }
} if err == nil && len(hops) > 0 {
if err == nil && len(hops) > 0 { mu.Lock()
allHops = append(allHops, hops) allHops = append(allHops, hops)
successfulTraces++ successfulTraces++
if model.EnableLoger { mu.Unlock()
Logger.Info(fmt.Sprintf("第%d次追踪 %s (%s) 成功,获得%d个hop", attempt, model.Ipv4Names[i], model.Ipv4s[i], len(hops))) if model.EnableLoger {
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,38 +80,48 @@ 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++ {
if model.EnableLoger { wg.Add(1)
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attempt, model.Ipv6Names[i], model.Ipv6s[i])) go func(attemptNum int) {
} defer wg.Done()
// 先尝试原始IP地址
hops, err := Trace(net.ParseIP(model.Ipv6s[i]))
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.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv6Names[i], model.Ipv6s[i]))
} }
// 如果原始IP失败尝试备选IP // 先尝试原始IP地址
if tryAltIPs := tryAlternativeIPs(model.Ipv6Names[i], "v6"); len(tryAltIPs) > 0 { hops, err := Trace(net.ParseIP(model.Ipv6s[i]))
for _, altIP := range tryAltIPs { if err != nil {
if model.EnableLoger { if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attempt, altIP, model.Ipv6Names[i])) Logger.Warn(fmt.Sprintf("第%d次追踪 %s (%s) 失败: %v", attemptNum, model.Ipv6Names[i], model.Ipv6s[i], err))
} }
hops, err = Trace(net.ParseIP(altIP)) // 如果原始IP失败尝试备选IP
if err == nil && len(hops) > 0 { if tryAltIPs := tryAlternativeIPs(model.Ipv6Names[i], "v6"); len(tryAltIPs) > 0 {
break // 成功找到可用IP for _, altIP := range tryAltIPs {
if model.EnableLoger {
Logger.Info(fmt.Sprintf("第%d次尝试备选IP %s 追踪 %s", attemptNum, altIP, model.Ipv6Names[i]))
}
hops, err = Trace(net.ParseIP(altIP))
if err == nil && len(hops) > 0 {
break // 成功找到可用IP
}
} }
} }
} }
} if err == nil && len(hops) > 0 {
if err == nil && len(hops) > 0 { mu.Lock()
allHops = append(allHops, hops) allHops = append(allHops, hops)
successfulTraces++ successfulTraces++
if model.EnableLoger { mu.Unlock()
Logger.Info(fmt.Sprintf("第%d次追踪 %s (%s) 成功,获得%d个hop", attempt, model.Ipv6Names[i], model.Ipv6s[i], len(hops))) if model.EnableLoger {
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地址"))