Documentation
¶
Overview ¶
Package trackingdomain verifies a Sending domain's Tracking domain (ADR 0038): a live DNS check that track.<domain> is a CNAME to the Instance's edge host, and the state that check keeps (pending -> dns_verified), and the HTTPS probe that moves a verified host to serving. The periodic job calls Check for every row.
The resolver and the clock are injected, so nothing here reads the network or the wall clock. A host is unique across the Instance among rows in dns_verified or serving; the partial unique index on the domain enforces it, and Check reports a lost race as ErrHostTaken by catching the violation, never by looking first. The state moves through a lifecycle table (ADR 0046) whose write is a compare-and-swap from the state Check read; a check that lost it returns lifecycle.ErrInvalidTransition and stores nothing.
Index ¶
Constants ¶
const ProbePath = "/.well-known/sphericon-tracking"
ProbePath is the well-known path a Tracking host serves for the serving check (ADR 0038): GET https://<host>/.well-known/sphericon-tracking answers 200 with ProbeValue(secret, host) as the plain-text body. The probe succeeds only when the body equals the value for the host it asked, so an answer from another host, a parked page or a proxy that is not ours does not pass.
Variables ¶
var ErrHostTaken = errors.New("tracking host is verified by another workspace")
ErrHostTaken means another Workspace holds the host in dns_verified or serving: this claim stays pending however correct its DNS is.
Functions ¶
func ProbeValue ¶
ProbeValue is the body ProbePath answers for host: a hex HMAC-SHA256 of the lowercase host under secret (the Instance JWT secret), so it is tied to the domain and cannot be guessed or copied from another host. Both sides compute it; nothing is stored.
Types ¶
type CNAMELookup ¶
CNAMELookup resolves the canonical name of a host. net.Resolver.LookupCNAME satisfies it; a host with no CNAME answers itself or a not-found error.
type Verifier ¶
type Verifier struct {
Lookup CNAMELookup
Target string
Now func() time.Time
HTTP Doer
Secret string
Events *events.Bus
}
Verifier checks Tracking domains against Target, the edge host the CNAME must reach. With HTTP and Secret set it also proves serving: a host reaches serving only when the HTTPS probe answers ProbeValue(Secret, host). Without HTTP no host ever becomes serving.
func (*Verifier) Check ¶
func (v *Verifier) Check(ctx context.Context, s *ent.Scoped, id int64) (sendingdomain.TrackingState, error)
Check re-verifies one Sending domain's Tracking domain from live DNS and, once the CNAME is right, the HTTPS probe, and stores the outcome: the check time always, and the state when it changes, with a TrackingDomainChanged event in the same transaction. DNS gone sends the state back to pending; a CNAME at Target with a failing probe is dns_verified (a serving host falls back to it); a passing probe is serving. A resolver failure other than not-found returns its error and changes nothing. It returns the resulting state, with ErrHostTaken when the host is held elsewhere; the row then carries the reason host_taken until a later check stores its outcome without losing the claim (the reason is cleared on every stored outcome, including an absent CNAME).