Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache type.
func (*Cache) Get ¶
func (n *Cache) Get(key uint64) (*Delegation, error)
(*Cache).Get returns the delegation entry for a key or an error.
func (*Cache) Set ¶
(*Cache).Set stores a delegation entry that expires ttl from now.
The lease must honour the parent-granted TTL. The former one-hour lower clamp inflated a short referral TTL (e.g. a 4s delegation) into a one-hour lease, which let a withdrawn child zone be kept alive indefinitely from its own authoritative NS answer — the ghost-domain vulnerability (GHSA-mqfw-f48p-2vc8). Only the upper bound is clamped now; a non-positive TTL is not cached at all (caching an already-expired entry is pointless and a zero TTL means "do not cache").
func (*Cache) SetUntil ¶ added in v1.7.3
(*Cache).SetUntil stores a delegation with an ABSOLUTE expiry, capped at the 12h ceiling. Resolver writes use this so a parent-granted deadline — possibly inherited from a shorter-lived ancestor — is stored verbatim rather than reconstructed from time.Until(deadline): any delay (including a scheduler pause) between computing the remaining duration and Set's now.Add(ttl) would otherwise restart the lease.
type Delegation ¶
Delegation represents a cache entry holding the authoritative servers for a zone plus the DS RRset that proves the delegation.
ExpiresAt is a single immutable absolute expiry (monotonic clock retained). Storing the absolute deadline — rather than a duration re-anchored at insertion — is what lets a descendant delegation inherit an ancestor's shorter lease without a scheduler pause between "compute remaining" and "store" silently re-inflating it (GHSA-mqfw-f48p-2vc8, Phoenix downward-delegation variant).
type Server ¶
type Server struct {
// place atomic members at the start to fix alignment for ARM32
Rtt int64
Count int64
Addr string
IPVersion IPVersion
// UDPAddr is Addr pre-parsed as *net.UDPAddr so the upstream
// exchange path can use net.DialUDP directly instead of going
// through Dialer.DialContext's string-parsing + dialParallel
// machinery. Nil only if Addr failed to parse — callers fall
// back to the string path in that case.
UDPAddr *net.UDPAddr
// contains filtered or unexported fields
}
Server type.
func NewServer ¶
NewServer return a new server. addr is expected to be an "IP:port" pair — the IP is parsed once here so upstream exchanges can skip Go's DialContext address-resolution path.
Addr is stored in canonical netip form (lowercase, compressed, 4-in-6 unmapped). Every producer builds addr from an IP literal (glue A/AAAA String, configured roots), so the canonical form is what comparison sites and map keys already see; deriving it here keeps one string per server instead of the parse chain's residue.
func NewServerFromAddrPort ¶ added in v1.8.0
NewServerFromAddrPort builds a Server straight from a decoded address — the netip-native producer path (glue records, NS-address lookups) that never materializes an intermediate "IP:port" string. The IP family is derived from the address itself, and the canonical string is created exactly once here for the key/log surfaces that need it.
func (*Server) CanonicalAddr ¶ added in v1.8.0
CanonicalAddr returns Addr together with whether it is already in the canonical spelling. A caller that keys on the endpoint can use the string as-is when this reports true, and must normalize it otherwise.
type Servers ¶
type Servers struct {
sync.RWMutex
// place atomic members at the start to fix alignment for ARM32
Called uint64
ErrorCount uint32
Zone string
List []*Server
Hosts []string
CheckingDisable bool
Checked bool
// contains filtered or unexported fields
}
Servers type.
func (*Servers) Fingerprint ¶
Fingerprint returns a stable identifier for the current List.Addr set. Callers must not hold the Servers lock.
func (*Servers) InvalidateFingerprint ¶
func (a *Servers) InvalidateFingerprint()
InvalidateFingerprint must be called whenever List is mutated. It has to run *before* the mutator releases the Servers write lock so readers can't observe the mutated List with a still-valid cached hash. A single atomic increment is cheap enough to keep inside the critical section.