mirror of
https://github.com/cloudflare/cloudflared.git
synced 2026-06-23 04:10:20 +00:00
9978cfd0d5
This PR implements all the dialers and resolvers needed to make pre-checks happen. So this task focuses on the following: 1. Implement the DNS probe: call DNSResolver.Resolve(region) 2. Implement the QUIC probe: call QUICDialer.DialQuic (handshake only, no stream opened) and record the result. 3. Implement the HTTP/2 probe: call TCPDialer.DialEdge (TCP + TLS handshake only, no frames sent) and record the result. 4. Implement the Management API probe: call ManagementDialer.DialContext to api.cloudflare.com:443 and record the result. 5. Export edgeDiscovery as EdgeDiscovery in edgediscovery/allregions/discovery.go so the pre-check can reuse the production DNS path. This sets up the main components to implement the checker.
83 lines
3.2 KiB
Go
83 lines
3.2 KiB
Go
package prechecks
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"net"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"github.com/quic-go/quic-go"
|
|
"github.com/rs/zerolog"
|
|
|
|
"github.com/cloudflare/cloudflared/connection/dialopts"
|
|
|
|
"github.com/cloudflare/cloudflared/edgediscovery/allregions"
|
|
)
|
|
|
|
// 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(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(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
|
|
// 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)
|
|
}
|
|
|
|
// 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.
|
|
DialContext(ctx context.Context, network, addr string) (net.Conn, error)
|
|
}
|