Bsically I'm writing an application that traceroutes a given set of hosts concurrently. I got the logic pretty much done but I'm having a slight problem with the timings. I am measuring the round-trip-times (rtt) of each packet with classic method of defining a `begin := time.Now()` variable just before sending the payloads, and then defining the `rtt := time.Since(begin)` variable right after receiving a response. The problem is that when I do this for multiple hosts, most of the timings start appearing in microseconds, as if the concurrent goroutines were triggering some sort of bug in the timing mechanism. When I probe a single host, I get the correct times so that's how I know that the logic and placement of each of these `begin` and `rtt` declarations is fine.
Here is an example ready to be compiled and run, showcasing the issue. See the outputs I get at the end: package main import ( "golang.org/x/net/ipv4" "net" "log" "fmt" "golang.org/x/net/icmp" "time" "os" "strings" "sync" ) func main() { fmt.Println("Probing 1 host \n\n") getRoutes("www.google.com") fmt.Println("Probing 2 hosts \n\n") getRoutes("www.facebook.com", "www.twitter.com") fmt.Println("Probing 3 hosts \n\n") getRoutes("www.google.com", "www.facebook.com", "www.twitter.com") } func getRoutes(hosts ...string) { ch := make(chan string, len(hosts)) var wg sync.WaitGroup wg.Add(len(hosts)) for _, host := range hosts { host := host //time.Sleep(1000*time.Millisecond) go func() { defer wg.Done(); trace(host, ch) }() } go func() { wg.Wait(); close(ch) }() for i := range ch { fmt.Println(i) } } func trace(host string, ch chan string) { // Tracing an IP packet route output := []string{} ips, err := net.LookupIP(host) if err != nil { log.Fatal(err) } var dst net.IPAddr for _, ip := range ips { if ip.To4() != nil { dst.IP = ip output = append(output, fmt.Sprintf("\n\nUsing %v for tracing an IP packet route to %s\n\n", dst.IP, host)) break } } if dst.IP == nil { log.Fatal("no A record found") } c, err := net.ListenPacket("ip4:1", "0.0.0.0") // ICMP for IPv4 if err != nil { log.Fatal(err) } defer c.Close() p := ipv4.NewPacketConn(c) id := os.Getpid() if err := p.SetControlMessage(ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface, true); err != nil { log.Fatal(err) } wm := icmp.Message{ Type: ipv4.ICMPTypeEcho, Code: 0, Body: &icmp.Echo{ ID: id & 0xffff, Data: []byte(host), }, } rb := make([]byte, 1500) Query: for i := 1; i <= 64; i++ { // up to 64 hops wm.Body.(*icmp.Echo).Seq = i wb, err := wm.Marshal(nil) if err != nil { log.Fatal(err) } if err := p.SetTTL(i); err != nil { log.Fatal(err) } begin := time.Now() if _, err := p.WriteTo(wb, nil, &dst); err != nil { log.Fatal(err) } if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil { log.Fatal(err) } n, cm, peer, err := p.ReadFrom(rb) if err != nil { if err, ok := err.(net.Error); ok && err.Timeout() { fmt.Printf("%v\t*\n", i) continue } log.Fatal(err) } rm, err := icmp.ParseMessage(1, rb[:n]) if err != nil { log.Fatal(err) } rtt := time.Since(begin) mb, _ := rm.Body.Marshal(1) switch rm.Type { case ipv4.ICMPTypeTimeExceeded: if strings.Contains(string(mb), host) { names, _ := net.LookupAddr(peer.String()) stats := fmt.Sprintf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm) output = append(output, stats) continue } case ipv4.ICMPTypeEchoReply: if strings.Contains(string(mb), host) { names, _ := net.LookupAddr(peer.String()) stats := fmt.Sprintf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm) output = append(output, stats) break Query } default: log.Printf("unknown ICMP message: %+v\n", rm) continue } } ch <- strings.Join(output, "") return } OUTPUTS: Probing 1 host Using 216.58.219.68 for tracing an IP packet route to www.google.com 1 192.168.1.1 [router] 1.285962ms ttl=64 src=192.168.1.1 dst=192.168.1.2 ifindex=2 5 84.16.11.234 [hu0-1-0-0-gractgtw1.net.telefonicaglobalsolutions.com.] 41.858369ms ttl=250 src=84.16.11.234 dst=192.168.1.2 ifindex=2 10 72.14.233.233 [] 78.03747ms ttl=54 src=72.14.233.233 dst=192.168.1.2 ifindex=2 11 216.58.219.68 [mia07s24-in-f68.1e100.net. mia07s24-in-f4.1e100.net. mia07s24-in-f4.1e100.net. mia07s24-in-f68.1e100.net.] 79.839308ms ttl=54 src=216.58.219.68 dst=192.168.1.2 ifindex=2 Probing 2 hosts Using 31.13.73.36 for tracing an IP packet route to www.facebook.com 1 192.168.1.1 [router] 1.642975ms ttl=64 src=192.168.1.1 dst=192.168.1.2 ifindex=2 6 10.7.120.193 [] 1.512576ms ttl=62 src=10.7.120.193 dst=192.168.1.2 ifindex=2 8 84.16.11.234 [hu0-1-0-0-gractgtw1.net.telefonicaglobalsolutions.com.] 88.916µs ttl=250 src=84.16.11.234 dst=192.168.1.2 ifindex=2 15 5.53.5.165 [ae4-grtmiabr1.net.telefonicaglobalsolutions.com.] 45.309µs ttl=243 src=5.53.5.165 dst=192.168.1.2 ifindex=2 18 213.140.33.165 [hu-0-11-0-0-grtmiana4.net.telefonicaglobalsolutions.com.] 67.448µs ttl=246 src=213.140.33.165 dst=192.168.1.2 ifindex=2 19 173.252.67.5 [] 201.578µs ttl=54 src=173.252.67.5 dst=192.168.1.2 ifindex=2 20 31.13.73.36 [edge-star-mini-shv-01-mia1.facebook.com.] 181.316µs ttl=86 src=31.13.73.36 dst=192.168.1.2 ifindex=2 Using 104.244.42.1 for tracing an IP packet route to www.twitter.com 2 192.168.1.1 [router] 1.049634ms ttl=64 src=192.168.1.1 dst=192.168.1.2 ifindex=2 3 10.7.120.193 [] 41.772495ms ttl=62 src=10.7.120.193 dst=192.168.1.2 ifindex=2 11 84.16.11.234 [hu0-1-0-0-gractgtw1.net.telefonicaglobalsolutions.com.] 1.070686ms ttl=250 src=84.16.11.234 dst=192.168.1.2 ifindex=2 13 84.16.15.128 [hu-1-5-0-0-4-grtmiabr6.net.telefonicaglobalsolutions.com. hu-1-5-0-0-4-grtmiabr6.red.telefonica-wholesale.net.] 140.145µs ttl=249 src=84.16.15.128 dst=192.168.1.2 ifindex=2 24 104.244.42.1 [] 126.108µs ttl=51 src=104.244.42.1 dst=192.168.1.2 ifindex=2 Probing 3 hosts Using 216.58.219.68 for tracing an IP packet route to www.google.com 1 192.168.1.1 [router] 1.387872ms ttl=64 src=192.168.1.1 dst=192.168.1.2 ifindex=2 12 84.16.11.234 [hu0-1-0-0-gractgtw1.net.telefonicaglobalsolutions.com.] 637.435µs ttl=250 src=84.16.11.234 dst=192.168.1.2 ifindex=2 14 10.7.120.193 [] 43.269µs ttl=62 src=10.7.120.193 dst=192.168.1.2 ifindex=2 20 72.14.233.233 [] 41.124µs ttl=54 src=72.14.233.233 dst=192.168.1.2 ifindex=2 21 216.58.219.68 [mia07s24-in-f68.1e100.net. mia07s24-in-f68.1e100.net. mia07s24-in-f4.1e100.net. mia07s24-in-f4.1e100.net.] 152.104µs ttl=54 src=216.58.219.68 dst=192.168.1.2 ifindex=2 Using 104.244.42.65 for tracing an IP packet route to www.twitter.com 2 192.168.1.1 [router] 438.191µs ttl=64 src=192.168.1.1 dst=192.168.1.2 ifindex=2 7 10.7.120.193 [] 1.387854ms ttl=62 src=10.7.120.193 dst=192.168.1.2 ifindex=2 11 84.16.11.234 [hu0-1-0-0-gractgtw1.net.telefonicaglobalsolutions.com.] 60.996µs ttl=250 src=84.16.11.234 dst=192.168.1.2 ifindex=2 29 5.53.3.243 [te0-9-0-5-grtmiabr6.net.telefonicaglobalsolutions.com.] 58.257µs ttl=249 src=5.53.3.243 dst=192.168.1.2 ifindex=2 36 104.244.42.65 [] 52.488µs ttl=52 src=104.244.42.65 dst=192.168.1.2 ifindex=2 Using 31.13.73.36 for tracing an IP packet route to www.facebook.com 1 192.168.1.1 [router] 1.359029ms ttl=64 src=192.168.1.1 dst=192.168.1.2 ifindex=2 5 10.7.120.193 [] 63.257µs ttl=62 src=10.7.120.193 dst=192.168.1.2 ifindex=2 12 84.16.11.234 [hu0-1-0-0-gractgtw1.net.telefonicaglobalsolutions.com.] 56.205µs ttl=250 src=84.16.11.234 dst=192.168.1.2 ifindex=2 28 213.140.33.165 [hu-0-11-0-0-grtmiana4.net.telefonicaglobalsolutions.com.] 57.08µs ttl=246 src=213.140.33.165 dst=192.168.1.2 ifindex=2 30 5.53.5.165 [ae4-grtmiabr1.net.telefonicaglobalsolutions.com.] 75.868µs ttl=243 src=5.53.5.165 dst=192.168.1.2 ifindex=2 32 74.119.79.178 [po102.psw01a.mia1.tfbnw.net.] 100.514µs ttl=53 src=74.119.79.178 dst=192.168.1.2 ifindex=2 33 213.140.43.120 [et6-1-0-4-grtmiana2.net.telefonicaglobalsolutions.com.] 141.644µs ttl=248 src=213.140.43.120 dst=192.168.1.2 ifindex=2 54 173.252.67.5 [] 56.98µs ttl=54 src=173.252.67.5 dst=192.168.1.2 ifindex=2 55 31.13.73.36 [edge-star-mini-shv-01-mia1.facebook.com.] 146.372µs ttl=86 src=31.13.73.36 dst=192.168.1.2 ifindex=2 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.