mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 22:59:58 +00:00
TUN-8729: implement network collection for diagnostic procedure
## Summary This PR adds implementation for windows & unix that collect the tracert.exe & traceroute output in the form of hops. Closes TUN-8729
This commit is contained in:
71
diagnostic/network/collector_windows.go
Normal file
71
diagnostic/network/collector_windows.go
Normal file
@@ -0,0 +1,71 @@
|
||||
//go:build windows
|
||||
|
||||
package diagnostic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type NetworkCollectorImpl struct{}
|
||||
|
||||
func (tracer *NetworkCollectorImpl) Collect(ctx context.Context, options TraceOptions) ([]*Hop, string, error) {
|
||||
args := []string{
|
||||
"-w",
|
||||
strconv.FormatInt(int64(options.timeout.Seconds()), 10),
|
||||
"-h",
|
||||
strconv.FormatUint(options.ttl, 10),
|
||||
// Do not resolve host names (can add 30+ seconds to run time)
|
||||
"-d",
|
||||
options.address,
|
||||
}
|
||||
if options.useV4 {
|
||||
args = append(args, "-4")
|
||||
} else {
|
||||
args = append(args, "-6")
|
||||
}
|
||||
command := exec.CommandContext(ctx, "tracert.exe", args...)
|
||||
|
||||
return decodeNetworkOutputToFile(command, DecodeLine)
|
||||
}
|
||||
|
||||
func DecodeLine(text string) (*Hop, error) {
|
||||
fields := strings.Fields(text)
|
||||
parts := []string{}
|
||||
filter := func(s string) bool { return s != "*" && s != "ms" }
|
||||
|
||||
for _, field := range fields {
|
||||
if filter(field) {
|
||||
parts = append(parts, field)
|
||||
}
|
||||
}
|
||||
|
||||
index, err := strconv.ParseUint(parts[0], 10, 8)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't parse index from timeout hop: %w", err)
|
||||
}
|
||||
|
||||
if len(parts) == 1 {
|
||||
return NewTimeoutHop(uint8(index)), nil
|
||||
}
|
||||
|
||||
domain := ""
|
||||
rtts := []time.Duration{}
|
||||
|
||||
for _, part := range parts[1:] {
|
||||
|
||||
rtt, err := strconv.ParseFloat(strings.TrimLeft(part, "<"), 64)
|
||||
|
||||
if err != nil {
|
||||
domain += part + " "
|
||||
} else {
|
||||
rtts = append(rtts, time.Duration(rtt*MicrosecondsFactor))
|
||||
}
|
||||
}
|
||||
domain, _ = strings.CutSuffix(domain, " ")
|
||||
return NewHop(uint8(index), domain, rtts), nil
|
||||
}
|
Reference in New Issue
Block a user