aboutsummaryrefslogtreecommitdiffstats
path: root/cache/cache.go
diff options
context:
space:
mode:
Diffstat (limited to 'cache/cache.go')
-rw-r--r--cache/cache.go24
1 files changed, 16 insertions, 8 deletions
diff --git a/cache/cache.go b/cache/cache.go
index 167ff08..087ba24 100644
--- a/cache/cache.go
+++ b/cache/cache.go
@@ -17,7 +17,6 @@ type Cache struct {
mu sync.RWMutex
done chan bool
now func() time.Time
- interval time.Duration
}
// Value wraps a DNS message stored in the cache.
@@ -53,22 +52,23 @@ func (v *Value) Answers() []string {
return answers
}
-// TTL returns the TTL of the cached value v.
+// TTL returns the time to live of the cached value v.
func (v *Value) TTL() time.Duration { return minTTL(v.msg) }
// New creates a new cache of given capacity.
-func New(capacity int) *Cache {
+func New(capacity int) *Cache { return newCache(capacity, time.Minute, time.Now) }
+
+func newCache(capacity int, interval time.Duration, now func() time.Time) *Cache {
if capacity < 0 {
capacity = 0
}
cache := &Cache{
- now: time.Now,
+ now: now,
capacity: capacity,
values: make(map[uint64]*Value, capacity),
done: make(chan bool),
- interval: time.Minute,
}
- go maintain(cache)
+ go maintain(cache, interval)
return cache
}
@@ -81,8 +81,8 @@ func NewKey(name string, qtype, qclass uint16) uint64 {
return h.Sum64()
}
-func maintain(cache *Cache) {
- ticker := time.NewTicker(cache.interval)
+func maintain(cache *Cache, interval time.Duration) {
+ ticker := time.NewTicker(interval)
for {
select {
case <-cache.done:
@@ -195,12 +195,20 @@ func min(x, y uint32) uint32 {
func minTTL(m *dns.Msg) time.Duration {
var ttl uint32 = 1<<32 - 1 // avoid importing math
+ // Choose the lowest TTL of answer, authority and additional sections.
for _, answer := range m.Answer {
ttl = min(answer.Header().Ttl, ttl)
}
for _, ns := range m.Ns {
ttl = min(ns.Header().Ttl, ttl)
}
+ for _, extra := range m.Extra {
+ // OPT (EDNS) is a pseudo record which uses TTL field for extended RCODE and flags
+ if extra.Header().Rrtype == dns.TypeOPT {
+ continue
+ }
+ ttl = min(extra.Header().Ttl, ttl)
+ }
return time.Duration(ttl) * time.Second
}