Something went wrong. Try again.
forked from tailscale/tailscale
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103// Copyright (c) Tailscale Inc & contributors// SPDX-License-Identifier: BSD-3-Clause
package prober_test
import ( "context" "crypto/tls" "flag" "fmt" "log" "net" "net/netip" "os" "os/signal" "time"
"tailscale.com/prober" "tailscale.com/types/logger")
const ( every30s = 30 * time.Second)
var ( hostname = flag.String("hostname", "tailscale.com", "hostname to probe") oneshot = flag.Bool("oneshot", true, "run probes once and exit") verbose = flag.Bool("verbose", false, "enable verbose logging"))
// This example demonstrates how to use ForEachAddr to create a TLS probe for// each IP address in the DNS record of a given hostname.func ExampleForEachAddr() { flag.Parse()
p := prober.New().WithSpread(true) if *oneshot { p = p.WithOnce(true) }
// This function is called every time we discover a new IP address to check. makeTLSProbe := func(addr netip.Addr) []*prober.Probe { pf := prober.TLSWithIP(netip.AddrPortFrom(addr, 443), &tls.Config{ServerName: *hostname}) if *verbose { logger := logger.WithPrefix(log.Printf, fmt.Sprintf("[tls %s]: ", addr)) pf = probeLogWrapper(logger, pf) }
probe := p.Run(fmt.Sprintf("website/%s/tls", addr), every30s, nil, pf) return []*prober.Probe{probe} }
// Determine whether to use IPv4 or IPv6 based on whether we can create // an IPv6 listening socket on localhost. sock, err := net.Listen("tcp", "[::1]:0") supportsIPv6 := err == nil if sock != nil { sock.Close() }
networks := []string{"ip4"} if supportsIPv6 { networks = append(networks, "ip6") }
var vlogf logger.Logf = logger.Discard if *verbose { vlogf = log.Printf }
// This is the outer probe that resolves the hostname and creates a new // TLS probe for each IP. p.Run("website/dns", every30s, nil, prober.ForEachAddr(*hostname, makeTLSProbe, prober.ForEachAddrOpts{ Logf: vlogf, Networks: networks, }))
defer log.Printf("done")
// Wait until all probes have run if we're running in oneshot mode. if *oneshot { p.Wait() return }
// Otherwise, wait until we get a signal. sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt) <-sigCh}
func probeLogWrapper(logf logger.Logf, pc prober.ProbeClass) prober.ProbeClass { return prober.ProbeClass{ Probe: func(ctx context.Context) error { logf("starting probe") err := pc.Probe(ctx) logf("probe finished with %v", err) return err }, }}