The TTL computation and assignment loops treat OPT record's Hdr.Ttl
as a regular TTL, but per RFC 6891 it encodes EDNS0 metadata
(ExtRCode|Version|Flags). This corrupts cached responses causing
systemd-resolved to reject them with EDNS version 255.
Also fix pointer aliasing: storeCache() stored raw *dns.Msg pointer
so subsequent mutations by Exchange() corrupted cached data.
- Skip OPT records in all TTL loops (Exchange + loadResponse)
- Use message.Copy() in storeCache() to isolate cache from mutations
The cache deduplication in Client.Exchange uses a channel-based lock
per DNS question. Waiting goroutines blocked on <-cond without context
awareness, causing them to accumulate indefinitely when the owning
goroutine's transport call stalls. Add select on ctx.Done() so waiters
respect context cancellation and timeouts.
The cache lookup was performed before rule matching, using the caller's
strategy (usually AsIS/0) instead of the resolved strategy. This caused
cache misses when ipv4_only was configured globally but the cache lookup
expected both A and AAAA records.
Remove LookupCache and ExchangeCache from Router, as the cache checks
inside client.Lookup and client.Exchange already handle caching correctly
after rule matching with the proper strategy and transport.