MCPcopy Create free account
hub / github.com/0xUnixIO/pulse / TracerouteHops

Method TracerouteHops

internal/nodeapi/traceroute.go:47–134  ·  view source on GitHub ↗

TracerouteHops 启动一次 traceroute,将每跳与终态(错误/完成)通过 channel 投递。 通道在追踪结束(reach 或超时)或 ctx 取消后关闭。

(ctx context.Context, req TracerouteRequest)

Source from the content-addressed store, hash-verified

45// TracerouteHops 启动一次 traceroute,将每跳与终态(错误/完成)通过 channel 投递。
46// 通道在追踪结束(reach 或超时)或 ctx 取消后关闭。
47func (a *API) TracerouteHops(ctx context.Context, req TracerouteRequest) <-chan TracerouteEvent {
48 out := make(chan TracerouteEvent, tracerouteMaxHops+2)
49 go func() {
50 defer close(out)
51 host := strings.TrimSpace(req.Host)
52 if host == "" {
53 out <- TracerouteEvent{Err: "host 参数不能为空"}
54 return
55 }
56 if strings.ContainsAny(host, " ;|&`$(){}[]<>\\'\"") {
57 out <- TracerouteEvent{Err: "host 包含非法字符"}
58 return
59 }
60 method := req.Method
61 if method != "tcp" {
62 method = "icmp"
63 }
64 port := req.Port
65 if port <= 0 || port > 65535 {
66 port = 80
67 }
68
69 addrs, err := net.DefaultResolver.LookupHost(ctx, host)
70 if err != nil || len(addrs) == 0 {
71 out <- TracerouteEvent{Err: fmt.Sprintf("DNS 解析失败: %v", err)}
72 return
73 }
74 destIP := net.ParseIP(addrs[0])
75 isIPv6 := destIP.To4() == nil
76
77 runCtx, cancel := context.WithTimeout(ctx, tracerouteTotalLimit)
78 defer cancel()
79
80 hopCh := make(chan TracerouteHop, tracerouteMaxHops)
81 doneCh := make(chan error, 1)
82 go func() {
83 var e error
84 if method == "tcp" {
85 if isIPv6 {
86 e = traceTCPv6(runCtx, destIP, port, hopCh)
87 } else {
88 e = traceTCPv4(runCtx, destIP.To4(), port, hopCh)
89 }
90 } else {
91 if isIPv6 {
92 e = traceICMPv6(runCtx, destIP, hopCh)
93 } else {
94 e = traceICMPv4(runCtx, destIP.To4(), hopCh)
95 }
96 }
97 doneCh <- e
98 }()
99
100 for {
101 select {
102 case hop, ok := <-hopCh:
103 if !ok {
104 hopCh = nil

Callers 1

Calls 7

traceTCPv6Function · 0.85
traceTCPv4Function · 0.85
traceICMPv6Function · 0.85
traceICMPv4Function · 0.85
LookupHostMethod · 0.80
DoneMethod · 0.65
ErrorMethod · 0.45

Tested by

no test coverage detected