fix: return SOA and NS records when queried for a record CNAMEd to origin (#7808)

* fix: return SOA and NS records when queried for a record CNAMEd to origin

Signed-off-by: Shiv Tyagi <shivtyagi3015@gmail.com>

* chore(test): add test for covering cname to origin scenario in file plugin

Signed-off-by: Shiv Tyagi <shivtyagi3015@gmail.com>

---------

Signed-off-by: Shiv Tyagi <shivtyagi3015@gmail.com>
This commit is contained in:
Shiv Tyagi
2026-01-22 08:05:48 +05:30
committed by GitHub
parent 1c9575747f
commit f1f0955cb9
3 changed files with 64 additions and 2 deletions

View File

@@ -331,7 +331,7 @@ func (z *Zone) externalLookup(ctx context.Context, state request.Request, elem *
targetName := rrs[0].(*dns.CNAME).Target
elem, _ = z.Search(targetName)
if elem == nil {
if elem == nil || (qtype == dns.TypeNS || qtype == dns.TypeSOA && targetName == z.origin) {
lookupRRs, result := z.doLookup(ctx, state, targetName, qtype)
rrs = append(rrs, lookupRRs...)
return rrs, z.ns(do), nil, result
@@ -351,7 +351,7 @@ Redo:
}
targetName := cname[0].(*dns.CNAME).Target
elem, _ = z.Search(targetName)
if elem == nil {
if elem == nil || (qtype == dns.TypeNS || qtype == dns.TypeSOA && targetName == z.origin) {
lookupRRs, result := z.doLookup(ctx, state, targetName, qtype)
rrs = append(rrs, lookupRRs...)
return rrs, z.ns(do), nil, result

View File

@@ -12,5 +12,6 @@ short 1 IN A 127.0.0.3
*.w 3600 IN TXT "Wildcard"
a.b.c.w IN TXT "Not a wildcard"
cname IN CNAME h.gtld-servers.net.
cname-origin IN CNAME @
service IN SRV 8080 10 10 @
`

View File

@@ -227,3 +227,64 @@ www 3600 IN A 127.0.0.53
t.Errorf("Failed to get address for CNAME, expected 127.0.0.53, got %s", x)
}
}
// TestFileCnameOrigin tests that CNAMEs pointing to origin are correctly resolved
func TestFileCnameOrigin(t *testing.T) {
cases := map[string]uint16{
"A": dns.TypeA,
"SOA": dns.TypeSOA,
"NS": dns.TypeNS,
}
name, rm, err := test.TempFile(".", exampleOrg)
if err != nil {
t.Fatalf("Failed to create zone: %s", err)
}
defer rm()
// Corefile with for example without proxy section.
corefile := `example.org:0 {
file ` + name + `
}`
i, udp, _, err := CoreDNSServerAndPorts(corefile)
if err != nil {
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
}
defer i.Stop()
for name, qtype := range cases {
t.Run(name, func(t *testing.T) {
m := new(dns.Msg)
m.SetQuestion("cname-origin.example.org.", qtype)
resp, err := dns.Exchange(m, udp)
if err != nil {
t.Fatalf("Expected to receive reply, but didn't: %s", err)
}
// Check minimum answer count (CNAME + target record)
if len(resp.Answer) < 2 {
t.Fatalf("Expected at least 2 RRs in answer section, got %d", len(resp.Answer))
}
// Verify first record is CNAME
if len(resp.Answer) > 0 && resp.Answer[0].Header().Rrtype != dns.TypeCNAME {
t.Errorf("Expected first RR to be CNAME, got %s", dns.TypeToString[resp.Answer[0].Header().Rrtype])
}
// Verify we have the queried type in the response
if len(resp.Answer) > 1 {
found := false
for _, rr := range resp.Answer[1:] {
if rr.Header().Rrtype == qtype {
found = true
break
}
}
if !found {
t.Errorf("Expected to find %s record in answer section", dns.TypeToString[qtype])
}
}
})
}
}