prechecks

package
v0.0.0-...-a453612 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CheckResult

type CheckResult struct {
	// Type identifies which probe produced this result. Used for severity
	// classification in hasHardFail and hasWarn.
	Type ProbeType

	// Component is the human-readable probe category shown in the table header
	// column
	Component string

	// Target is the address or resource that was probed
	Target string

	// ProbeStatus is the outcome of the probe.
	ProbeStatus Status

	// Details is a short description of the result shown in the table
	Details string

	// Action is non-empty when ProbeStatus is Fail and contains a human-readable
	// remediation instruction
	Action string
}

CheckResult holds the outcome of one individual connectivity probe.

type Config

type Config struct {
	// Region is the optional cloudflared --region flag value. When non-empty
	// the pre-check probes the regional edge hostnames instead of the global ones.
	Region string

	// Timeout is the maximum wall-clock duration allowed for the entire
	// pre-check suite to complete.
	Timeout time.Duration

	// IPVersion controls which address families are probed for transport
	// checks. It mirrors the --edge-ip-version CLI flag so that the pre-check
	// exercises the same code paths the tunnel itself will use.
	IPVersion allregions.ConfigIPVersion
}

Config controls the behavior of a pre-check Run().

type DNSResolver

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(region string) ([][]*allregions.EdgeAddr, error)
}

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 EdgeDNSResolver

type EdgeDNSResolver struct {
	Log *zerolog.Logger
}

func (*EdgeDNSResolver) Resolve

func (r *EdgeDNSResolver) Resolve(region string) ([][]*allregions.EdgeAddr, error)

type EdgeQUICDialer

type EdgeQUICDialer struct{}

func (*EdgeQUICDialer) DialQuic

func (d *EdgeQUICDialer) DialQuic(
	ctx context.Context,
	quicConfig *quic.Config,
	tlsConfig *tls.Config,
	addr netip.AddrPort,
	localAddr net.IP,
	connIndex uint8,
	logger *zerolog.Logger,
	opts dialopts.DialOpts,
) (quic.Connection, error)

type EdgeTCPDialer

type EdgeTCPDialer struct{}

func (*EdgeTCPDialer) DialEdge

func (d *EdgeTCPDialer) DialEdge(
	ctx context.Context,
	timeout time.Duration,
	tlsConfig *tls.Config,
	addr *net.TCPAddr,
	localIP net.IP,
) (net.Conn, error)

type ManagementDialer

type ManagementDialer interface {
	// DialContext opens a TCP connection to the given network address. The
	// caller is responsible for closing the connection.
	DialContext(ctx context.Context, network, addr string) (net.Conn, error)
}

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 NetManagementDialer

type NetManagementDialer struct {
	Dialer net.Dialer
}

func (*NetManagementDialer) DialContext

func (d *NetManagementDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

type ProbeType

type ProbeType int

ProbeType identifies which connectivity probe produced a CheckResult. It is used by hasHardFail and hasWarn to evaluate severity without matching against human-readable strings.

const (
	ProbeTypeDNS           ProbeType = iota // DNS resolution
	ProbeTypeQUIC                           // UDP/QUIC transport
	ProbeTypeHTTP2                          // TCP/HTTP2 transport
	ProbeTypeManagementAPI                  // Cloudflare management API
)

type QUICDialer

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
	// connection. connIndex is used for UDP port reuse bookkeeping consistent
	// with the production dial path.
	DialQuic(
		ctx context.Context,
		quicConfig *quic.Config,
		tlsConfig *tls.Config,
		addr netip.AddrPort,
		localAddr net.IP,
		connIndex uint8,
		logger *zerolog.Logger,
		opts dialopts.DialOpts,
	) (quic.Connection, 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 Report

type Report struct {
	// RunID is a unique identifier for this pre-check run. It is included in
	// every structured log line so that all results from a single invocation
	// can be correlated across log aggregation systems.
	RunID uuid.UUID

	// Results contains one entry per executed probe, in the order they were
	// collected.
	Results []CheckResult

	// SuggestedProtocol is the connection protocol the pre-checks recommend
	// based on transport probe results. Nil when no valid protocol is available
	// (e.g., when both transports fail or DNS is unresolvable).
	SuggestedProtocol *connection.Protocol
}

Report aggregates all CheckResults produced by a single Run() invocation. Pre-checks run in parallel with tunnel initialization and are purely diagnostic: the Report is displayed to the user but never gates startup.

func Run

func Run(ctx context.Context, caCert string, cfg Config, log *zerolog.Logger, runDialers RunDialers) Report

Run executes the following connectivity pre-checks:

  1. DNS resolution (sequential – transport probes depend on its output).
  2. QUIC, HTTP/2, and Management API probes run concurrently.

Each failed probe is retried up to maxRetries times with exponential backoff. The suite is bounded by cfg.Timeout (defaultTimeout if zero).

func (Report) LogEvent

func (r Report) LogEvent(logger *zerolog.Logger)

LogEvent emits each CheckResult as a structured zerolog log line, followed by a final summary event. This is the JSON-logging equivalent of String(). Every line carries run_id so all results from a single invocation can be correlated.

func (Report) String

func (r Report) String() string

String renders the Report as a human-readable table suitable for os.Stdout.

type RunDialers

type RunDialers struct {
	DNSResolver      DNSResolver
	TCPDialer        TCPDialer
	QUICDialer       QUICDialer
	ManagementDialer ManagementDialer
}

RunDialers holds the injectable dependencies for Run(). Production callers build this with real implementations; tests supply mocks.

type Status

type Status int

Status represents the outcome of a single connectivity pre-check.

const (
	// Pass indicates the check completed successfully.
	Pass Status = iota
	// Fail indicates the check did not succeed. Whether this is a hard failure
	// or a degraded-but-functional state depends on which probe(s) failed — see
	// Report.hasHardFail and Report.hasWarn.
	Fail
	// Skip indicates the check was not executed because a prerequisite
	// check (typically DNS) failed first.
	Skip
)

func (Status) String

func (s Status) String() string

String returns the canonical display name for a Status value.

type TCPDialer

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(ctx context.Context, timeout time.Duration, tlsConfig *tls.Config, addr *net.TCPAddr, localIP net.IP) (net.Conn, 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 TransportResults

type TransportResults struct {
	QUIC          []CheckResult // one per region
	HTTP2         []CheckResult // one per region
	ManagementAPI CheckResult   // single target, no regions
}

TransportResults holds the per-region results for each transport probe type. Each slice has one entry per DNS-resolved region, in the same order as dnsResults.

func (TransportResults) Collect

func (tr TransportResults) Collect() []CheckResult

Collect returns all results as a slice in a consistent order for reporting: all QUIC rows first (one per region), then all HTTP2 rows, then Management API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL