sendOutboundUserPing sends a non-privileged ICMP (or ICMPv6) ping to dstIP with the given timeout.
(dstIP netip.Addr, timeout time.Duration)
| 25 | |
| 26 | // sendOutboundUserPing sends a non-privileged ICMP (or ICMPv6) ping to dstIP with the given timeout. |
| 27 | func (ns *Impl) sendOutboundUserPing(dstIP netip.Addr, timeout time.Duration) error { |
| 28 | var err error |
| 29 | switch runtime.GOOS { |
| 30 | case "windows": |
| 31 | var out []byte |
| 32 | out, err = exec.Command("ping", "-n", "1", "-w", "3000", dstIP.String()).CombinedOutput() |
| 33 | if err == nil && !windowsPingOutputIsSuccess(dstIP, out) { |
| 34 | // TODO(bradfitz,nickkhyl): return the actual ICMP error we heard back to the caller? |
| 35 | // For now we just drop it. |
| 36 | err = errors.New("unsuccessful ICMP reply received") |
| 37 | } |
| 38 | case "freebsd": |
| 39 | // Note: 2000 ms is actually 1 second + 2,000 |
| 40 | // milliseconds extra for 3 seconds total. |
| 41 | // See https://github.com/tailscale/tailscale/pull/3753 for details. |
| 42 | ping := "ping" |
| 43 | if dstIP.Is6() { |
| 44 | ping = "ping6" |
| 45 | } |
| 46 | err = exec.Command(ping, "-c", "1", "-W", "2000", dstIP.String()).Run() |
| 47 | case "openbsd": |
| 48 | ping := "ping" |
| 49 | if dstIP.Is6() { |
| 50 | ping = "ping6" |
| 51 | } |
| 52 | err = exec.Command(ping, "-c", "1", "-w", "3", dstIP.String()).Run() |
| 53 | case "android": |
| 54 | ping := "/system/bin/ping" |
| 55 | if dstIP.Is6() { |
| 56 | ping = "/system/bin/ping6" |
| 57 | } |
| 58 | err = exec.Command(ping, "-c", "1", "-w", "3", dstIP.String()).Run() |
| 59 | default: |
| 60 | ping := "ping" |
| 61 | if isSynology { |
| 62 | ping = "/bin/ping" |
| 63 | } |
| 64 | cmd := exec.Command(ping, "-c", "1", "-W", "3", dstIP.String()) |
| 65 | if buildfeatures.HasSynology && isSynology && os.Getuid() != 0 { |
| 66 | // On DSM7 we run as non-root and need to pass |
| 67 | // CAP_NET_RAW if our binary has it. |
| 68 | setAmbientCapsRaw(cmd) |
| 69 | } |
| 70 | err = cmd.Run() |
| 71 | } |
| 72 | return err |
| 73 | } |
no test coverage detected