diff --git a/prechecks/probes.go b/prechecks/probes.go index e3400a38..b99e8216 100644 --- a/prechecks/probes.go +++ b/prechecks/probes.go @@ -62,6 +62,8 @@ const ( region2Fed = "fed-region2.v2.argotunnel.com" ) +// EdgeDNSResolver implements DNSResolver for the standard DNS-based edge +// discovery path. type EdgeDNSResolver struct { Log *zerolog.Logger } @@ -70,6 +72,20 @@ func (r *EdgeDNSResolver) Resolve(region string) ([][]*allregions.EdgeAddr, erro return allregions.EdgeDiscovery(r.Log, allregions.RegionalServiceName(region)) } +// StaticEdgeDNSResolver implements DNSResolver for the --edge flag path. +type StaticEdgeDNSResolver struct { + Addrs []string + Log *zerolog.Logger +} + +func (r *StaticEdgeDNSResolver) Resolve(_ string) ([][]*allregions.EdgeAddr, error) { + resolved := allregions.ResolveAddrs(r.Addrs, r.Log) + if len(resolved) == 0 { + return nil, fmt.Errorf("failed to resolve any edge address") + } + return [][]*allregions.EdgeAddr{resolved}, nil +} + type EdgeTCPDialer struct{} func (d *EdgeTCPDialer) DialEdge( diff --git a/prechecks/resolvers.go b/prechecks/resolvers.go index 0262230e..b1372fd0 100644 --- a/prechecks/resolvers.go +++ b/prechecks/resolvers.go @@ -16,41 +16,20 @@ import ( ) // DNSResolver abstracts edge DNS discovery used by DNS probes. -// -// The production implementation wraps allregions.EdgeDiscovery -// (edgediscovery/allregions/discovery.go), which performs an SRV lookup for -// _v2-origintunneld._tcp.argotunnel.com, falls back to DNS-over-TLS when the -// system resolver fails, and resolves each discovered hostname via -// net.LookupIP. The returned slice already has each address tagged with -// .IPVersion = V4 or V6. type DNSResolver interface { - // Resolve performs edge discovery for the given region string (empty for - // global, "us" / "fed" for regional endpoints) and returns the resolved - // addresses grouped by CNAME target, mirroring the structure returned by - // allregions.EdgeDiscovery. + // Resolve performs edge discovery for the given region string and returns + // the resolved edge regions. Resolve(region string) ([][]*allregions.EdgeAddr, error) } // TCPDialer abstracts the TCP + TLS handshake used by HTTP/2 connectivity probes. -// -// The production implementation wraps edgediscovery.DialEdge -// (edgediscovery/dial.go), which is the same function supervisor/tunnel.go -// uses for production HTTP/2 connections. Reusing it ensures the pre-check -// validates the identical dial path the tunnel will take. type TCPDialer interface { - // DialEdge dials the given edge TCP address with TLS, respecting the - // provided timeout, and returns the established connection. The caller is - // responsible for closing the connection. + // DialEdge dials the given edge TCP address with TLS and returns the + // established connection. The caller is responsible for closing the connection. DialEdge(ctx context.Context, timeout time.Duration, tlsConfig *tls.Config, addr *net.TCPAddr, localIP net.IP) (net.Conn, error) } // QUICDialer abstracts the UDP + QUIC handshake used by QUIC connectivity probes. -// -// The production implementation wraps connection.DialQuic -// (connection/quic.go), which is the same function supervisor/tunnel.go uses -// for production QUIC connections. The pre-check performs a handshake only — -// no streams are opened and no RPC frames are sent — to avoid triggering the -// OTD registration timeout described in TUN-6732. type QUICDialer interface { // DialQuic performs a QUIC handshake to the given edge address and returns // the established connection. The caller is responsible for closing the @@ -70,11 +49,6 @@ type QUICDialer interface { // ManagementDialer abstracts the TCP dial to api.cloudflare.com:443 used by // the Management API probe. -// -// A successful TCP connection (no TLS handshake required) is sufficient to -// confirm that port 443 is reachable. This probe is always a soft failure: -// the tunnel can run without it, but automatic software updates will be -// unavailable. type ManagementDialer interface { // DialContext opens a TCP connection to the given network address. The // caller is responsible for closing the connection.