diff --git a/nameserver/cache.go b/nameserver/cache.go index 32451725..96be41dc 100644 --- a/nameserver/cache.go +++ b/nameserver/cache.go @@ -129,9 +129,12 @@ func (e *cacheEntry) setReply(reply *dns.Msg, ttl int, flags uint8, now time.Tim prevValidUntil = e.validUntil } - e.Status = stResolved - e.Flags = flags - e.putTime = now + // make sure we do not overwrite noLocalReplies entries + if flags&CacheNoLocalReplies != 0 { + if e.Flags&CacheNoLocalReplies != 0 { + return false + } + } if ttl != nullTTL { e.validUntil = now.Add(time.Second * time.Duration(ttl)) @@ -145,8 +148,14 @@ func (e *cacheEntry) setReply(reply *dns.Msg, ttl int, flags uint8, now time.Tim } } e.validUntil = now.Add(time.Second * time.Duration(minTTL)) + } else { + Warning.Printf("[cache] no valid TTL could be calculated") } + e.Status = stResolved + e.Flags = flags + e.putTime = now + if reply != nil { e.reply = *reply e.ReplyLen = reply.Len() diff --git a/nameserver/cache_test.go b/nameserver/cache_test.go index 47830dfd..492438bb 100644 --- a/nameserver/cache_test.go +++ b/nameserver/cache_test.go @@ -196,11 +196,24 @@ func TestCacheEntries(t *testing.T) { question3 := &questionMsg3.Question[0] t.Logf("Checking that a entry with CacheNoLocalReplies return an error") - l.Put(questionMsg3, nil, nullTTL, CacheNoLocalReplies) + l.Put(questionMsg3, nil, DefaultCacheNegLocalTTL, CacheNoLocalReplies) resp, err = l.Get(questionMsg3, minUDPSize) wt.AssertNil(t, resp, "Get() response with CacheNoLocalReplies") - wt.AssertNotNil(t, err, "Get() error with CacheNoLocalReplies") + wt.AssertTrue(t, err == errNoLocalReplies, "Get() error with CacheNoLocalReplies") + t.Logf("Checking that more Put's do not make the negative TTL longer") + clk.Add(time.Duration(DefaultCacheNegLocalTTL/2) * time.Second) + l.Put(questionMsg3, nil, DefaultCacheNegLocalTTL, CacheNoLocalReplies) + clk.Add(time.Duration(1) * time.Second) + l.Put(questionMsg3, nil, DefaultCacheNegLocalTTL, CacheNoLocalReplies) + clk.Add(time.Duration(1) * time.Second) + l.Put(questionMsg3, nil, DefaultCacheNegLocalTTL, CacheNoLocalReplies) + resp, err = l.Get(questionMsg3, minUDPSize) + wt.AssertNil(t, resp, "Get() response with CacheNoLocalReplies") + wt.AssertTrue(t, err == errNoLocalReplies, "Get() error with CacheNoLocalReplies") + + clk.Add(time.Duration(DefaultCacheNegLocalTTL/2) * time.Second) + t.Logf("Checking that we get an expired response after %f seconds", DefaultCacheNegLocalTTL) clk.Add(time.Second * time.Duration(DefaultCacheNegLocalTTL+1)) t.Logf("Checking that we get an expired response after %d seconds", DefaultCacheNegLocalTTL) resp, err = l.Get(questionMsg3, minUDPSize)