plugin/cache: Fix filtering (#4148)
The filtering of DNSSEC records in the cache plugin was not done correctly. Also the change to introduced this bug didn't take into account that the cache - by virtue of differentiating between DNSSEC and no-DNSSEC - relied on not copying the data from the cache. This change copies and then filters the data and factors the filtering into a function that is used in two places (albeit with on ugly boolean parameters to prevent copying things twice). Add tests, do_test.go is moved to test/cache_test.go because the OPT handing is done outside of the cache plugin. The core server re-attaches the correct OPT when replying, so that makes for a better e2e test. Added small unit test for filterRRslice and an explicit test that asks for DNSSEC first and then plain, and vice versa to test cache behavior. Fixes: #4146 Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
parent
1a1ce9a9c8
commit
35b40a84f2
7 changed files with 220 additions and 163 deletions
|
@ -46,6 +46,13 @@ func TestLookupCache(t *testing.T) {
|
|||
testCase(t, "short.example.org.", udp, 1, 5)
|
||||
})
|
||||
|
||||
t.Run("DNSSEC OPT", func(t *testing.T) {
|
||||
testCaseDNSSEC(t, "example.org.", udp, 4096)
|
||||
})
|
||||
|
||||
t.Run("DNSSEC OPT", func(t *testing.T) {
|
||||
testCaseDNSSEC(t, "example.org.", udp, 0)
|
||||
})
|
||||
}
|
||||
|
||||
func testCase(t *testing.T, name, addr string, expectAnsLen int, expectTTL uint32) {
|
||||
|
@ -53,7 +60,7 @@ func testCase(t *testing.T, name, addr string, expectAnsLen int, expectTTL uint3
|
|||
m.SetQuestion(name, dns.TypeA)
|
||||
resp, err := dns.Exchange(m, addr)
|
||||
if err != nil {
|
||||
t.Fatal("Expected to receive reply, but didn't")
|
||||
t.Fatalf("Expected to receive reply, but didn't: %s", err)
|
||||
}
|
||||
|
||||
if len(resp.Answer) != expectAnsLen {
|
||||
|
@ -65,3 +72,41 @@ func testCase(t *testing.T, name, addr string, expectAnsLen int, expectTTL uint3
|
|||
t.Errorf("Expected TTL to be %d, got %d", expectTTL, ttl)
|
||||
}
|
||||
}
|
||||
|
||||
func testCaseDNSSEC(t *testing.T, name, addr string, bufsize int) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(name, dns.TypeA)
|
||||
|
||||
if bufsize > 0 {
|
||||
o := &dns.OPT{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeOPT}}
|
||||
o.SetDo()
|
||||
o.SetUDPSize(uint16(bufsize))
|
||||
m.Extra = append(m.Extra, o)
|
||||
}
|
||||
resp, err := dns.Exchange(m, addr)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected to receive reply, but didn't: %s", err)
|
||||
}
|
||||
|
||||
if len(resp.Extra) == 0 && bufsize == 0 {
|
||||
// no OPT, this is OK
|
||||
return
|
||||
}
|
||||
|
||||
opt := resp.Extra[len(resp.Extra)-1]
|
||||
if x, ok := opt.(*dns.OPT); !ok && bufsize > 0 {
|
||||
t.Fatalf("Expected OPT RR, got %T", x)
|
||||
}
|
||||
if bufsize > 0 {
|
||||
if !opt.(*dns.OPT).Do() {
|
||||
t.Errorf("Expected DO bit to be set, got false")
|
||||
}
|
||||
if x := opt.(*dns.OPT).UDPSize(); int(x) != bufsize {
|
||||
t.Errorf("Expected %d bufsize, got %d", bufsize, x)
|
||||
}
|
||||
} else {
|
||||
if opt.Header().Rrtype == dns.TypeOPT {
|
||||
t.Errorf("Expected no OPT RR, but got one: %s", opt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue