mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 22:49:58 +00:00
TUN-8762: fix argument order when invoking tracert and modify network info output parsing.
## Summary The windows code path has three bugs: * the -4 and -6 option cannot be passed in the last position * since there are some lines in the command output that are not parsable the collection fails to parse any kind of output * the timeout hop is not correctly parsed This PR also guards the parsing code against empty domains Closes TUN-8762
This commit is contained in:
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
type DecodeLineFunc func(text string) (*Hop, error)
|
||||
|
||||
func decodeNetworkOutputToFile(command *exec.Cmd, fn DecodeLineFunc) ([]*Hop, string, error) {
|
||||
func decodeNetworkOutputToFile(command *exec.Cmd, decodeLine DecodeLineFunc) ([]*Hop, string, error) {
|
||||
stdout, err := command.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error piping traceroute's output: %w", err)
|
||||
@@ -26,32 +26,41 @@ func decodeNetworkOutputToFile(command *exec.Cmd, fn DecodeLineFunc) ([]*Hop, st
|
||||
// otherwise the process can become a zombie
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
tee := io.TeeReader(stdout, buf)
|
||||
hops, err := Decode(tee, fn)
|
||||
hops, err := Decode(tee, decodeLine)
|
||||
// regardless of success of the decoding
|
||||
// consume all output to have available in buf
|
||||
_, _ = io.ReadAll(tee)
|
||||
|
||||
if werr := command.Wait(); werr != nil {
|
||||
return nil, "", fmt.Errorf("error finishing traceroute: %w", werr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// consume all output to have available in buf
|
||||
io.ReadAll(tee)
|
||||
// This is already a TracerouteError no need to wrap it
|
||||
return nil, buf.String(), err
|
||||
}
|
||||
|
||||
return hops, "", nil
|
||||
}
|
||||
|
||||
func Decode(reader io.Reader, fn DecodeLineFunc) ([]*Hop, error) {
|
||||
func Decode(reader io.Reader, decodeLine DecodeLineFunc) ([]*Hop, error) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
|
||||
var hops []*Hop
|
||||
|
||||
for scanner.Scan() {
|
||||
text := scanner.Text()
|
||||
hop, err := fn(text)
|
||||
if text == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
hop, err := decodeLine(text)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding output line: %w", err)
|
||||
// This continue is here on the error case because there are lines at the start and end
|
||||
// that may not be parsable. (check windows tracert output)
|
||||
// The skip is here because aside from the start and end lines the other lines should
|
||||
// always be parsable without errors.
|
||||
continue
|
||||
}
|
||||
|
||||
hops = append(hops, hop)
|
||||
|
Reference in New Issue
Block a user