mirror of
https://github.com/oneclickvirt/backtrace.git
synced 2026-05-22 17:40:10 +08:00
Compare commits
8 Commits
v0.0.8-202
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
238e885bae | ||
|
|
ce8555f149 | ||
|
|
026f9784e4 | ||
|
|
91a1634ce9 | ||
|
|
bea9e7562a | ||
|
|
9a4e7dccca | ||
|
|
5bbd411a8e | ||
|
|
d0c66a9d39 |
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
@ -5,12 +5,15 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * 0'
|
- cron: '0 0 * * 0'
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
fetch-ipv6-prefixes:
|
fetch-ipv6-prefixes:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 检出代码
|
- name: 检出代码
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|||||||
11
.github/workflows/ci.yaml
vendored
11
.github/workflows/ci.yaml
vendored
@ -3,19 +3,22 @@ name: CI
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go: ['1.22.x']
|
go: ['stable']
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
|
|
||||||
@ -30,7 +33,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git config --global user.name 'github-actions'
|
git config --global user.name 'github-actions'
|
||||||
git config --global user.email 'github-actions@github.com'
|
git config --global user.email 'github-actions@github.com'
|
||||||
TAG="v0.0.8-$(date +'%Y%m%d%H%M%S')"
|
TAG="v0.0.9-$(date +'%Y%m%d%H%M%S')"
|
||||||
git tag $TAG
|
git tag $TAG
|
||||||
git push origin $TAG
|
git push origin $TAG
|
||||||
echo "TAG=$TAG" >> $GITHUB_ENV
|
echo "TAG=$TAG" >> $GITHUB_ENV
|
||||||
|
|||||||
16
.github/workflows/main.yaml
vendored
16
.github/workflows/main.yaml
vendored
@ -9,16 +9,19 @@ on:
|
|||||||
# types: [published]
|
# types: [published]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build and Test
|
name: Build and Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: 'stable'
|
go-version: 'stable'
|
||||||
|
|
||||||
@ -44,10 +47,10 @@ jobs:
|
|||||||
needs: build
|
needs: build
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: 'stable'
|
go-version: 'stable'
|
||||||
|
|
||||||
@ -55,7 +58,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p bin
|
mkdir -p bin
|
||||||
cd cmd
|
cd cmd
|
||||||
CGO_ENABLED=0 GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} go build \
|
CGO_ENABLED=0 GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} GOARM=${{ matrix.goarm }} go build \
|
||||||
-o ../bin/backtrace-${{ matrix.goos }}-${{ matrix.goarch }} \
|
-o ../bin/backtrace-${{ matrix.goos }}-${{ matrix.goarch }} \
|
||||||
-v \
|
-v \
|
||||||
-ldflags="-extldflags=-static -s -w" \
|
-ldflags="-extldflags=-static -s -w" \
|
||||||
@ -89,9 +92,6 @@ jobs:
|
|||||||
goarch: amd64
|
goarch: amd64
|
||||||
- goos: windows
|
- goos: windows
|
||||||
goarch: arm64
|
goarch: arm64
|
||||||
- goos: windows
|
|
||||||
goarch: arm
|
|
||||||
goarm: 7
|
|
||||||
- goos: darwin
|
- goos: darwin
|
||||||
goarch: arm64
|
goarch: arm64
|
||||||
- goos: linux
|
- goos: linux
|
||||||
|
|||||||
@ -75,7 +75,7 @@ rm -rf /usr/bin/backtrace
|
|||||||
## 在Golang中使用
|
## 在Golang中使用
|
||||||
|
|
||||||
```
|
```
|
||||||
go get github.com/oneclickvirt/backtrace@v0.0.8-20251109090457
|
go get github.com/oneclickvirt/backtrace@v0.0.9-20260521161358
|
||||||
```
|
```
|
||||||
|
|
||||||
## 概览图
|
## 概览图
|
||||||
|
|||||||
@ -117,7 +117,10 @@ func getSVGPath(ip string) (string, error) {
|
|||||||
client := req.C().ImpersonateChrome()
|
client := req.C().ImpersonateChrome()
|
||||||
url := fmt.Sprintf("https://bgp.tools/prefix/%s#connectivity", ip)
|
url := fmt.Sprintf("https://bgp.tools/prefix/%s#connectivity", ip)
|
||||||
resp, err := executeWithRetry(client, url, defaultRetryConfig)
|
resp, err := executeWithRetry(client, url, defaultRetryConfig)
|
||||||
if err == nil {
|
if err == nil && resp != nil {
|
||||||
|
if resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
body := resp.String()
|
body := resp.String()
|
||||||
re := regexp.MustCompile(`<img[^>]+id="pathimg"[^>]+src="([^"]+)"`)
|
re := regexp.MustCompile(`<img[^>]+id="pathimg"[^>]+src="([^"]+)"`)
|
||||||
matches := re.FindStringSubmatch(body)
|
matches := re.FindStringSubmatch(body)
|
||||||
@ -142,7 +145,8 @@ func downloadSVG(svgPath string) (string, error) {
|
|||||||
uuid := uuid.NewString()
|
uuid := uuid.NewString()
|
||||||
url := fmt.Sprintf("https://bgp.tools%s?%s&loggedin", svgPath, uuid)
|
url := fmt.Sprintf("https://bgp.tools%s?%s&loggedin", svgPath, uuid)
|
||||||
resp, err := executeWithRetry(client, url, defaultRetryConfig)
|
resp, err := executeWithRetry(client, url, defaultRetryConfig)
|
||||||
if err == nil {
|
if err == nil && resp != nil && resp.Body != nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
bodyBytes, err := io.ReadAll(resp.Body)
|
bodyBytes, err := io.ReadAll(resp.Body)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return string(bodyBytes), nil
|
return string(bodyBytes), nil
|
||||||
|
|||||||
@ -7,6 +7,14 @@ import (
|
|||||||
"github.com/oneclickvirt/backtrace/model"
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func safeTraceCall(fn func()) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fn()
|
||||||
|
}
|
||||||
|
|
||||||
func BackTrace(enableIpv6 bool) string {
|
func BackTrace(enableIpv6 bool) string {
|
||||||
if model.CachedIcmpData == "" || model.ParsedIcmpTargets == nil || time.Since(model.CachedIcmpDataFetchTime) > time.Hour {
|
if model.CachedIcmpData == "" || model.ParsedIcmpTargets == nil || time.Since(model.CachedIcmpDataFetchTime) > time.Hour {
|
||||||
model.CachedIcmpData = getData(model.IcmpTargets)
|
model.CachedIcmpData = getData(model.IcmpTargets)
|
||||||
@ -26,10 +34,16 @@ func BackTrace(enableIpv6 bool) string {
|
|||||||
t = time.After(time.Second * 10)
|
t = time.After(time.Second * 10)
|
||||||
)
|
)
|
||||||
for i := range model.Ipv4s {
|
for i := range model.Ipv4s {
|
||||||
go trace(c, i)
|
idx := i
|
||||||
|
go safeTraceCall(func() {
|
||||||
|
trace(c, idx)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
for i := range model.Ipv6s {
|
for i := range model.Ipv6s {
|
||||||
go traceIPv6(c, i, ipv4Count)
|
idx := i
|
||||||
|
go safeTraceCall(func() {
|
||||||
|
traceIPv6(c, idx, ipv4Count)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
loopIPv4v6:
|
loopIPv4v6:
|
||||||
for range s {
|
for range s {
|
||||||
@ -62,7 +76,10 @@ func BackTrace(enableIpv6 bool) string {
|
|||||||
t = time.After(time.Second * 10)
|
t = time.After(time.Second * 10)
|
||||||
)
|
)
|
||||||
for i := range model.Ipv4s {
|
for i := range model.Ipv4s {
|
||||||
go trace(c, i)
|
idx := i
|
||||||
|
go safeTraceCall(func() {
|
||||||
|
trace(c, idx)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
loopIPv4:
|
loopIPv4:
|
||||||
for range s {
|
for range s {
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
2400:9380:9009
|
2400:9380:9009
|
||||||
2400:9380:9020
|
2400:9380:9020
|
||||||
2400:9380:9021
|
2400:9380:9021
|
||||||
2400:9380:9040
|
|
||||||
2400:9380:9050
|
2400:9380:9050
|
||||||
2400:9380:9051
|
2400:9380:9051
|
||||||
2400:9380:9060
|
2400:9380:9060
|
||||||
@ -19,7 +18,6 @@
|
|||||||
2400:9380:9121
|
2400:9380:9121
|
||||||
2400:9380:9220
|
2400:9380:9220
|
||||||
2400:9380:9221
|
2400:9380:9221
|
||||||
2400:9380:9240
|
|
||||||
2400:9380:9250
|
2400:9380:9250
|
||||||
2400:9380:9251
|
2400:9380:9251
|
||||||
2400:9380:9260
|
2400:9380:9260
|
||||||
@ -98,6 +96,8 @@
|
|||||||
240e:649:dc0f
|
240e:649:dc0f
|
||||||
240e:64e
|
240e:64e
|
||||||
240e:64e:de0
|
240e:64e:de0
|
||||||
|
240e:64e:dec
|
||||||
|
240e:64e:ded
|
||||||
240e:650
|
240e:650
|
||||||
240e:659:f100
|
240e:659:f100
|
||||||
240e:65f
|
240e:65f
|
||||||
|
|||||||
@ -15,3 +15,5 @@
|
|||||||
2620:107:4008:d23c
|
2620:107:4008:d23c
|
||||||
2620:107:4008:d23d
|
2620:107:4008:d23d
|
||||||
2620:107:4008:d261
|
2620:107:4008:d261
|
||||||
|
2620:107:4008:d270
|
||||||
|
2620:107:4008:d271
|
||||||
|
|||||||
@ -862,6 +862,7 @@
|
|||||||
2409:8734:2451
|
2409:8734:2451
|
||||||
2409:8734:c01
|
2409:8734:c01
|
||||||
2409:8734:c10
|
2409:8734:c10
|
||||||
|
2409:8735
|
||||||
2409:874c
|
2409:874c
|
||||||
2409:874c:c10
|
2409:874c:c10
|
||||||
2409:874d
|
2409:874d
|
||||||
|
|||||||
@ -233,7 +233,10 @@ func (t *Tracer) serveData(from net.IP, b []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if msg.Type == ipv4.ICMPTypeEchoReply {
|
if msg.Type == ipv4.ICMPTypeEchoReply {
|
||||||
echo := msg.Body.(*icmp.Echo)
|
echo, ok := msg.Body.(*icmp.Echo)
|
||||||
|
if !ok || echo == nil {
|
||||||
|
return errUnsupportedProtocol
|
||||||
|
}
|
||||||
return t.serveReply(from, &packet{from, uint16(echo.ID), 1, time.Now()})
|
return t.serveReply(from, &packet{from, uint16(echo.ID), 1, time.Now()})
|
||||||
}
|
}
|
||||||
b = getReplyData(msg)
|
b = getReplyData(msg)
|
||||||
|
|||||||
@ -58,6 +58,10 @@ func extractIpv4ASNsFromHops(hops []*Hop, enableLogger bool) []string {
|
|||||||
|
|
||||||
// trace IPv4追踪函数
|
// trace IPv4追踪函数
|
||||||
func trace(ch chan Result, i int) {
|
func trace(ch chan Result, i int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
}
|
||||||
|
}()
|
||||||
if model.EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
@ -72,6 +76,10 @@ func trace(ch chan Result, i int) {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(attemptNum int) {
|
go func(attemptNum int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
}
|
||||||
|
}()
|
||||||
if model.EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv4Names[i], model.Ipv4s[i]))
|
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv4Names[i], model.Ipv4s[i]))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,10 +43,21 @@ func (t *Tracer) serveIPv6(conn *ipv6.PacketConn) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if model.EnableLoger {
|
srcAddr, ok := src.(*net.IPAddr)
|
||||||
Logger.Info(fmt.Sprintf("收到IPv6响应: 来源=%v, 跳数=%d", src, cm.HopLimit))
|
if !ok || srcAddr == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hopLimit := 0
|
||||||
|
if cm != nil {
|
||||||
|
hopLimit = cm.HopLimit
|
||||||
|
}
|
||||||
|
if model.EnableLoger {
|
||||||
|
Logger.Info(fmt.Sprintf("收到IPv6响应: 来源=%v, 跳数=%d", srcAddr, hopLimit))
|
||||||
|
}
|
||||||
|
fromIP := srcAddr.IP
|
||||||
|
if fromIP == nil {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
fromIP := src.(*net.IPAddr).IP
|
|
||||||
err = t.serveData(fromIP, buf[:n])
|
err = t.serveData(fromIP, buf[:n])
|
||||||
if err != nil && model.EnableLoger {
|
if err != nil && model.EnableLoger {
|
||||||
Logger.Warn("处理IPv6数据失败: " + err.Error())
|
Logger.Warn("处理IPv6数据失败: " + err.Error())
|
||||||
@ -73,6 +84,10 @@ func extractIpv6ASNsFromHops(hops []*Hop, enableLogger bool) []string {
|
|||||||
|
|
||||||
// traceIPv6 IPv6追踪函数
|
// traceIPv6 IPv6追踪函数
|
||||||
func traceIPv6(ch chan Result, i int, offset int) {
|
func traceIPv6(ch chan Result, i int, offset int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
}
|
||||||
|
}()
|
||||||
if model.EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
@ -87,6 +102,10 @@ func traceIPv6(ch chan Result, i int, offset int) {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(attemptNum int) {
|
go func(attemptNum int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
}
|
||||||
|
}()
|
||||||
if model.EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv6Names[i], model.Ipv6s[i]))
|
Logger.Info(fmt.Sprintf("第%d次尝试追踪 %s (%s)", attemptNum, model.Ipv6Names[i], model.Ipv6s[i]))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ func checkCdn(testUrl string) string {
|
|||||||
Logger.Info(fmt.Sprintf("Testing CDN: %s", url))
|
Logger.Info(fmt.Sprintf("Testing CDN: %s", url))
|
||||||
}
|
}
|
||||||
resp, err := client.R().Get(url)
|
resp, err := client.R().Get(url)
|
||||||
if err == nil {
|
if err == nil && resp != nil && resp.Body != nil {
|
||||||
b, err := io.ReadAll(resp.Body)
|
b, err := io.ReadAll(resp.Body)
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
if err == nil && strings.Contains(string(b), "success") {
|
if err == nil && strings.Contains(string(b), "success") {
|
||||||
@ -92,7 +92,7 @@ func getData(endpoint string) string {
|
|||||||
Logger.Info(fmt.Sprintf("Using CDN: %s", url))
|
Logger.Info(fmt.Sprintf("Using CDN: %s", url))
|
||||||
}
|
}
|
||||||
resp, err := client.R().Get(url)
|
resp, err := client.R().Get(url)
|
||||||
if err == nil {
|
if err == nil && resp != nil && resp.Body != nil {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
b, err := io.ReadAll(resp.Body)
|
b, err := io.ReadAll(resp.Body)
|
||||||
if err == nil && !strings.Contains(string(b), "error") {
|
if err == nil && !strings.Contains(string(b), "error") {
|
||||||
@ -112,7 +112,7 @@ func getData(endpoint string) string {
|
|||||||
Logger.Info(fmt.Sprintf("Trying direct connection: %s", endpoint))
|
Logger.Info(fmt.Sprintf("Trying direct connection: %s", endpoint))
|
||||||
}
|
}
|
||||||
resp, err := client.R().Get(endpoint)
|
resp, err := client.R().Get(endpoint)
|
||||||
if err == nil {
|
if err == nil && resp != nil && resp.Body != nil {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
b, err := io.ReadAll(resp.Body)
|
b, err := io.ReadAll(resp.Body)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
27
cmd/main.go
27
cmd/main.go
@ -32,9 +32,23 @@ type ConcurrentResults struct {
|
|||||||
// backtraceError error
|
// backtraceError error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func safeGo(wg *sync.WaitGroup, fn func()) {
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fn()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
go func() {
|
go func() {
|
||||||
http.Get("https://hits.spiritlhl.net/backtrace.svg?action=hit&title=Hits&title_bg=%23555555&count_bg=%230eecf8&edge_flat=false")
|
resp, err := http.Get("https://hits.spiritlhl.net/backtrace.svg?action=hit&title=Hits&title_bg=%23555555&count_bg=%230eecf8&edge_flat=false")
|
||||||
|
if err == nil && resp != nil && resp.Body != nil {
|
||||||
|
resp.Body.Close()
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
fmt.Println(Green("Repo:"), Yellow("https://github.com/oneclickvirt/backtrace"))
|
fmt.Println(Green("Repo:"), Yellow("https://github.com/oneclickvirt/backtrace"))
|
||||||
var showVersion, showIpInfo, help, ipv6 bool
|
var showVersion, showIpInfo, help, ipv6 bool
|
||||||
@ -62,6 +76,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("get ip info err %v \n", err.Error())
|
fmt.Printf("get ip info err %v \n", err.Error())
|
||||||
} else {
|
} else {
|
||||||
|
defer rsp.Body.Close()
|
||||||
err = json.NewDecoder(rsp.Body).Decode(&info)
|
err = json.NewDecoder(rsp.Body).Decode(&info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("json decode err %v \n", err.Error())
|
fmt.Printf("json decode err %v \n", err.Error())
|
||||||
@ -106,8 +121,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
if targetIP != "" {
|
if targetIP != "" {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
safeGo(&wg, func() {
|
||||||
defer wg.Done()
|
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
result, err := bgptools.GetPoPInfo(targetIP)
|
result, err := bgptools.GetPoPInfo(targetIP)
|
||||||
results.bgpError = err
|
results.bgpError = err
|
||||||
@ -119,14 +133,13 @@ func main() {
|
|||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
safeGo(&wg, func() {
|
||||||
defer wg.Done()
|
|
||||||
result := backtrace.BackTrace(useIPv6)
|
result := backtrace.BackTrace(useIPv6)
|
||||||
results.backtraceResult = result
|
results.backtraceResult = result
|
||||||
}()
|
})
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
if results.bgpResult != "" {
|
if results.bgpResult != "" {
|
||||||
fmt.Print(results.bgpResult)
|
fmt.Print(results.bgpResult)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package model
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
const BackTraceVersion = "v0.0.8"
|
const BackTraceVersion = "v0.0.9"
|
||||||
|
|
||||||
var EnableLoger = false
|
var EnableLoger = false
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user