Documentation
¶
Index ¶
- func AcquireMsg() *dns.Msg
- func ReleaseMsg(m *dns.Msg)
- func SetCacheSizeFuncs(positive, negative func() int)
- func SetMetricsInstance(m *CacheMetrics)
- func UpdateCacheSizeMetrics()
- type Cache
- func (c *Cache) ForEachEntry(fn func(positive bool, key uint64, entry *CacheEntry) bool)
- func (c *Cache) Name() string
- func (c *Cache) Purge(q dns.Question)
- func (c *Cache) ServeDNS(ctx context.Context, ch *middleware.Chain)
- func (c *Cache) Set(key uint64, msg *dns.Msg)
- func (c *Cache) SetPrefetchQueryer(q middleware.Queryer)
- func (c *Cache) SetQueryer(q middleware.Queryer)
- func (c *Cache) Stats() map[string]any
- func (c *Cache) Stop()
- func (c *Cache) Store() middleware.Store
- type CacheConfig
- type CacheEntry
- type CacheKey
- type CacheMetrics
- type DCache
- type NegativeCache
- type PositiveCache
- type PrefetchQueue
- type PrefetchRequest
- type ResponseWriter
- type Store
- func (s *Store) ForEach(fn func(positive bool, key uint64, entry *CacheEntry) bool)
- func (s *Store) Get(req *dns.Msg) (*dns.Msg, bool)
- func (s *Store) Lookup(req *dns.Msg) (*CacheEntry, bool)
- func (s *Store) LookupByKey(key uint64) (*CacheEntry, bool)
- func (s *Store) LookupByKeyVerified(key uint64, q dns.Question) (*CacheEntry, bool)
- func (s *Store) NegativeLen() int
- func (s *Store) PositiveLen() int
- func (s *Store) Purge(q dns.Question)
- func (s *Store) SetEntryWithKey(key uint64, entry *CacheEntry, mt dnsutil.ResponseType)
- func (s *Store) SetFromResponse(resp *dns.Msg, keyCD bool)
- func (s *Store) SetFromResponseScoped(key uint64, resp *dns.Msg)
- func (s *Store) SetFromResponseWithKey(key uint64, resp *dns.Msg)
- type TTLManager
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AcquireMsg ¶ added in v1.0.0
AcquireMsg returns an empty msg from pool with pre-allocated slices.
func SetCacheSizeFuncs ¶ added in v1.6.1
func SetCacheSizeFuncs(positive, negative func() int)
SetCacheSizeFuncs sets the functions to get cache sizes
func SetMetricsInstance ¶ added in v1.6.1
func SetMetricsInstance(m *CacheMetrics)
SetMetricsInstance sets the metrics instance for hit rate calculation
func UpdateCacheSizeMetrics ¶ added in v1.6.1
func UpdateCacheSizeMetrics()
UpdateCacheSizeMetrics updates the cache size gauges
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache is the cache implementation.
func (*Cache) ForEachEntry ¶ added in v1.6.2
func (c *Cache) ForEachEntry(fn func(positive bool, key uint64, entry *CacheEntry) bool)
ForEachEntry iterates over positive and negative cache entries. Iteration is not atomic with concurrent updates. Returning false from fn stops iteration.
func (*Cache) Purge ¶ added in v1.6.4
(*Cache).Purge removes positive and negative cache entries for q under both CD=true and CD=false. Implements middleware.Purger so the api purge endpoint can invalidate cache state without synthesising a CHAOS-NULL request.
func (*Cache) ServeDNS ¶
func (c *Cache) ServeDNS(ctx context.Context, ch *middleware.Chain)
(*Cache).ServeDNS serveDNS implements the middleware.Handler interface.
func (*Cache) Set ¶
(*Cache).Set set adds a new element to the cache. Provided for API compatibility (prefetch worker, plugin callers). Internally goes through Store; the entry is constructed with origTTL adjusted to the real upstream TTL so subsequent prefetch decisions don't miscalculate from the post-Calculate (clamped) value.
func (*Cache) SetPrefetchQueryer ¶ added in v1.6.4
func (c *Cache) SetPrefetchQueryer(q middleware.Queryer)
(*Cache).SetPrefetchQueryer installs the Queryer used by the prefetch worker. The prefetch sub-pipeline excludes the cache middleware so a refresh reaches the upstream resolver / forwarder instead of returning its own about-to-expire entry.
func (*Cache) SetQueryer ¶ added in v1.6.4
func (c *Cache) SetQueryer(q middleware.Queryer)
(*Cache).SetQueryer installs the Queryer used for internal client-shaped work (CNAME chase on cache writeback, future DNAME target lookup from the resolver). Called once from sdns.go startup.
func (*Cache) Stop ¶ added in v1.5.0
func (c *Cache) Stop()
(*Cache).Stop stop gracefully shuts down the cache.
func (*Cache) Store ¶ added in v1.6.4
func (c *Cache) Store() middleware.Store
(*Cache).Store returns the storage facade, typed as middleware.Store so Cache satisfies middleware.StoreProvider for auto-wiring in middleware.Setup. External callers that need the full *Store surface can type-assert.
type CacheConfig ¶ added in v1.5.0
type CacheConfig struct {
Size int
Prefetch int
PositiveTTL time.Duration
NegativeTTL time.Duration
MinTTL time.Duration
MaxTTL time.Duration
RateLimit int
// ECSMaxTTL caps the lifetime of cache entries keyed under an
// ECS scope. Geo-routed answers tend to go stale faster than
// the resolver's general MaxTTL would suggest — a CDN
// re-pointing a /24 between PoPs is normal traffic. Zero
// disables the cap (scoped entries live as long as their
// upstream TTL allowed). Populated from cfg.ECS.CacheLimitTTL.
ECSMaxTTL time.Duration
}
CacheConfig holds cache configuration with validation.
func (CacheConfig) Validate ¶ added in v1.5.0
func (cc CacheConfig) Validate() error
(CacheConfig).Validate validate checks if the configuration is valid.
type CacheEntry ¶ added in v1.5.0
type CacheEntry struct {
// contains filtered or unexported fields
}
CacheEntry represents an immutable cache entry.
func NewCacheEntry ¶ added in v1.5.0
NewCacheEntry creates a new cache entry from a DNS message.
func NewCacheEntryWithKey ¶ added in v1.6.0
NewCacheEntryWithKey creates a new cache entry with a specific key for rate limiting
func NewScopedCacheEntry ¶ added in v1.7.0
NewScopedCacheEntry creates a cache entry that's been keyed under an ECS scope. The flag suppresses prefetch (the worker has no client IP to derive the scope from on refresh).
func (*CacheEntry) GetRateLimiter ¶ added in v1.6.0
func (e *CacheEntry) GetRateLimiter() *rate.Limiter
(*CacheEntry).GetRateLimiter returns the shared rate limiter for this entry
func (*CacheEntry) IsExpired ¶ added in v1.5.0
func (e *CacheEntry) IsExpired() bool
(*CacheEntry).IsExpired isExpired checks if the cache entry has expired.
func (*CacheEntry) PrefetchEligible ¶ added in v1.7.0
func (e *CacheEntry) PrefetchEligible() bool
PrefetchEligible reports whether the prefetch worker may refresh this entry. Scoped entries are skipped because the worker has no client IP, so a refresh would lose the ECS scope and create a shared-key entry instead — wrong answer for the wrong audience.
func (*CacheEntry) ShouldPrefetch ¶ added in v1.5.0
func (e *CacheEntry) ShouldPrefetch(threshold int) bool
(*CacheEntry).ShouldPrefetch shouldPrefetch checks if this entry should be prefetched.
func (*CacheEntry) TTL ¶ added in v1.5.0
func (e *CacheEntry) TTL() int
(*CacheEntry).TTL TTL returns the remaining TTL in seconds.
type CacheKey ¶ added in v1.5.0
CacheKey represents a structured cache key.
Scope is the ECS prefix (RFC 7871) the authority claimed its answer is scoped to. The zero value means "shared" — an entry keyed with no scope is reachable by any client, which is the pre-Stage-2 default and how non-ECS traffic and SCOPE=0 authority answers continue to behave after the upgrade.
func (CacheKey) Hash ¶ added in v1.5.0
(CacheKey).Hash returns the cache key hash. Routes to cache.KeyWithPrefix when Scope is valid (family + bit-length + address are all folded in so /22 and /24 of the same address don't alias), and to the legacy cache.Key — bit-identical to pre-Stage-2 — when Scope is the zero value, so old entries keep hitting after upgrade. A /0 scope collapses to the unscoped key because a /0 answer is semantically "global", same as no scope.
type CacheMetrics ¶ added in v1.5.0
type CacheMetrics struct {
// contains filtered or unexported fields
}
CacheMetrics tracks cache performance metrics.
func (*CacheMetrics) Eviction ¶ added in v1.5.0
func (m *CacheMetrics) Eviction()
(*CacheMetrics).Eviction eviction records a cache eviction.
func (*CacheMetrics) Hit ¶ added in v1.5.0
func (m *CacheMetrics) Hit()
(*CacheMetrics).Hit hit records a cache hit.
func (*CacheMetrics) Miss ¶ added in v1.5.0
func (m *CacheMetrics) Miss()
(*CacheMetrics).Miss miss records a cache miss.
func (*CacheMetrics) Prefetch ¶ added in v1.5.0
func (m *CacheMetrics) Prefetch()
(*CacheMetrics).Prefetch prefetch records a prefetch operation.
func (*CacheMetrics) Stats ¶ added in v1.5.0
func (m *CacheMetrics) Stats() (hits, misses, evictions, prefetches int64)
(*CacheMetrics).Stats stats returns current metrics.
type DCache ¶ added in v1.6.4
type DCache interface {
Get(key uint64) (*CacheEntry, bool)
Set(key uint64, entry *CacheEntry)
Remove(key uint64)
Len() int
}
DCache defines the interface for DNS cache implementations.
type NegativeCache ¶ added in v1.5.0
type NegativeCache struct {
// contains filtered or unexported fields
}
NegativeCache handles error DNS responses.
func NewNegativeCache ¶ added in v1.5.0
func NewNegativeCache(size int, minTTL, maxTTL time.Duration, metrics *CacheMetrics) *NegativeCache
NewNegativeCache creates a new negative cache.
func (*NegativeCache) Get ¶ added in v1.5.0
func (nc *NegativeCache) Get(key uint64) (*CacheEntry, bool)
(*NegativeCache).Get get retrieves an entry from the negative cache. Hit/Miss metrics are NOT recorded here — see PositiveCache.Get.
func (*NegativeCache) Len ¶ added in v1.5.0
func (nc *NegativeCache) Len() int
(*NegativeCache).Len len returns the number of entries in the cache.
func (*NegativeCache) Remove ¶ added in v1.5.0
func (nc *NegativeCache) Remove(key uint64)
(*NegativeCache).Remove remove deletes an entry from the negative cache.
func (*NegativeCache) Set ¶ added in v1.5.0
func (nc *NegativeCache) Set(key uint64, entry *CacheEntry)
(*NegativeCache).Set set stores an entry in the negative cache.
type PositiveCache ¶ added in v1.5.0
type PositiveCache struct {
// contains filtered or unexported fields
}
PositiveCache handles successful DNS responses.
func NewPositiveCache ¶ added in v1.5.0
func NewPositiveCache(size int, minTTL, maxTTL time.Duration, metrics *CacheMetrics) *PositiveCache
NewPositiveCache creates a new positive cache.
func (*PositiveCache) Get ¶ added in v1.5.0
func (pc *PositiveCache) Get(key uint64) (*CacheEntry, bool)
(*PositiveCache).Get get retrieves an entry from the positive cache. Hit/Miss metrics are NOT recorded here — checkCache consults both positive and negative caches per request and records the aggregate result once, so pushing metrics in here would double-count both sides of a single miss.
func (*PositiveCache) Len ¶ added in v1.5.0
func (pc *PositiveCache) Len() int
(*PositiveCache).Len len returns the number of entries in the cache.
func (*PositiveCache) Remove ¶ added in v1.5.0
func (pc *PositiveCache) Remove(key uint64)
(*PositiveCache).Remove remove deletes an entry from the positive cache.
func (*PositiveCache) Set ¶ added in v1.5.0
func (pc *PositiveCache) Set(key uint64, entry *CacheEntry)
(*PositiveCache).Set set stores an entry in the positive cache.
type PrefetchQueue ¶ added in v1.5.0
type PrefetchQueue struct {
// contains filtered or unexported fields
}
PrefetchQueue manages prefetch requests with worker pool.
func NewPrefetchQueue ¶ added in v1.5.0
func NewPrefetchQueue(workers, queueSize int, metrics *CacheMetrics) *PrefetchQueue
NewPrefetchQueue creates a new prefetch queue.
func (*PrefetchQueue) Add ¶ added in v1.5.0
func (pq *PrefetchQueue) Add(req PrefetchRequest) bool
(*PrefetchQueue).Add add queues a prefetch request.
func (*PrefetchQueue) Stop ¶ added in v1.5.0
func (pq *PrefetchQueue) Stop()
(*PrefetchQueue).Stop stop gracefully shuts down the prefetch queue.
type PrefetchRequest ¶ added in v1.5.0
type PrefetchRequest struct {
Request *dns.Msg
Key uint64
Cache *Cache // Reference to the cache to store prefetched results
Entry *CacheEntry // Entry that claimed the prefetch; used to release the claim on failure/drop
}
PrefetchRequest represents a DNS query to be prefetched.
type ResponseWriter ¶
type ResponseWriter struct {
middleware.ResponseWriter
// contains filtered or unexported fields
}
ResponseWriter is the response writer for cache.
type Store ¶ added in v1.6.4
type Store struct {
// contains filtered or unexported fields
}
Store is the cache backing for the cache middleware. It owns nothing directly — the positive/negative sub-caches are constructed by Cache.New and shared with Store — but it centralises classification, keying, and TTL handling so callers outside ServeDNS (resolver sub-queries, queryer-driven prefetch, future API purge wiring) don't need to understand the wire-write rules in ResponseWriter.WriteMsg.
SetFromResponse keys on the caller-supplied keyCD rather than on resp.CheckingDisabled to make the keying contract explicit at every call site — Forwarder and Resolver both temporarily mutate CD on the upstream request, and silent reliance on resp.CheckingDisabled is the kind of thing that splits CD=1 and CD=0 lookups across stale entries when a future change forgets to restore.
func NewStore ¶ added in v1.6.4
func NewStore(positive *PositiveCache, negative *NegativeCache, cfg CacheConfig) *Store
NewStore returns a Store backed by the supplied sub-caches. The caches are shared with the surrounding *Cache; this constructor does not allocate them.
func (*Store) ForEach ¶ added in v1.6.4
func (s *Store) ForEach(fn func(positive bool, key uint64, entry *CacheEntry) bool)
ForEach iterates over positive then negative entries. Returning false from fn stops iteration. Iteration is not atomic with concurrent updates.
func (*Store) Get ¶ added in v1.6.4
Get returns a materialised cached response for req. Reply header/ID/CD/AD interaction is handled by CacheEntry.ToMsg, which needs req for SetReply.
func (*Store) Lookup ¶ added in v1.6.4
func (s *Store) Lookup(req *dns.Msg) (*CacheEntry, bool)
Lookup returns the cache entry for req without materialising a response. Used by callers that need to inspect TTL or prefetch flags before deciding whether to consume the entry.
func (*Store) LookupByKey ¶ added in v1.6.4
func (s *Store) LookupByKey(key uint64) (*CacheEntry, bool)
LookupByKey is the pre-keyed form of Lookup, used by hot paths inside the cache middleware that already computed the key.
Callers MUST verify the returned entry's question against the request (use LookupByKeyVerified, or compare via entryMatchesQuestion): the map key is a non-cryptographic 64-bit xxhash of the key preimage, so a hash collision would otherwise serve one query's answer to another.
func (*Store) LookupByKeyVerified ¶ added in v1.7.1
LookupByKeyVerified is LookupByKey plus a full-key check: it confirms the stored entry's question matches q before returning it. Without this, two distinct questions whose preimages collide under xxhash64 would silently serve each other's answers — and because qnames are attacker-chosen, a collision can be searched for offline and used to poison the cache.
func (*Store) NegativeLen ¶ added in v1.6.4
NegativeLen returns the number of entries in the negative cache.
func (*Store) PositiveLen ¶ added in v1.6.4
PositiveLen returns the number of entries in the positive cache.
func (*Store) Purge ¶ added in v1.6.4
Purge removes both CD=true and CD=false entries for q from positive and negative caches, including ECS-scoped entries.
Scoped entries don't have a deterministic key the caller could reproduce without enumerating every (qname, scope) the cache has ever seen — there's no per-qname index. We sweep them with ForEach: collect matching keys in one pass (snapshotting the per-segment locks individually), then Remove outside the iteration to avoid mutate-during-iterate hazards.
O(n) on the cache size; Purge is rare (explicit operator API call) so the linear scan is acceptable. If purge becomes hot, a per-qname index would lift this back to O(matches).
func (*Store) SetEntryWithKey ¶ added in v1.6.4
func (s *Store) SetEntryWithKey(key uint64, entry *CacheEntry, mt dnsutil.ResponseType)
SetEntryWithKey replaces a stored entry directly. Used by Cache.Set's compatibility path where a caller already constructed the CacheEntry (e.g. prefetch worker writing back a response with adjusted origTTL).
func (*Store) SetFromResponse ¶ added in v1.6.4
SetFromResponse classifies resp (positive / NXDOMAIN+NODATA / SERVFAIL) and stores it under (resp.Question[0], keyCD). CHAOS signalling responses are skipped, matching ResponseWriter.WriteMsg.
func (*Store) SetFromResponseScoped ¶ added in v1.7.0
SetFromResponseScoped is SetFromResponseWithKey for entries that were keyed under an ECS scope (RFC 7871 §7.1.2). The entry's PrefetchEligible is false — the prefetch worker has no client IP to derive ECS from, so refreshing a scoped entry would lose its scope and store the wrong-audience answer.
type TTLManager ¶ added in v1.5.0
type TTLManager struct {
// contains filtered or unexported fields
}
TTLManager manages TTL calculations.
func NewTTLManager ¶ added in v1.5.0
func NewTTLManager(min, max time.Duration) TTLManager
NewTTLManager creates a new TTL manager.