ProbeIP dials ip:port with cfg.ConnectTimeout and measures RTT. This is a plain TCP connect; no TLS. Returns Reachable=true only on successful three-way handshake.
(ctx context.Context, ip netip.Addr, port uint16, timeout time.Duration)
| 23 | // plain TCP connect; no TLS. Returns Reachable=true only on successful |
| 24 | // three-way handshake. |
| 25 | func ProbeIP(ctx context.Context, ip netip.Addr, port uint16, timeout time.Duration) IPResult { |
| 26 | if port == 0 { |
| 27 | port = 443 |
| 28 | } |
| 29 | if timeout <= 0 { |
| 30 | timeout = 2 * time.Second |
| 31 | } |
| 32 | r := IPResult{IP: ip, Port: port} |
| 33 | dialCtx, cancel := context.WithTimeout(ctx, timeout) |
| 34 | defer cancel() |
| 35 | start := time.Now() |
| 36 | conn, err := (&net.Dialer{}).DialContext(dialCtx, "tcp", |
| 37 | net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port))) |
| 38 | r.RTT = time.Since(start) |
| 39 | if err != nil { |
| 40 | r.Err = err.Error() |
| 41 | return r |
| 42 | } |
| 43 | _ = conn.Close() |
| 44 | r.Reachable = true |
| 45 | return r |
| 46 | } |
| 47 | |
| 48 | // ProbeIPs runs ProbeIP concurrently. Output order matches input. |
| 49 | func ProbeIPs(ctx context.Context, ips []string, port uint16, timeout time.Duration, |