plugin/file: preserve case in SRV record names and targets per RFC 6763 (#7402)

This commit is contained in:
Syed Azeez 2025-07-15 07:26:59 +05:30 committed by GitHub
parent ff88ad37f7
commit d8906ce610
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 5 deletions

View File

@ -2,6 +2,7 @@ package tree
import ( import (
"bytes" "bytes"
"strings"
"github.com/miekg/dns" "github.com/miekg/dns"
) )
@ -27,8 +28,8 @@ func less(a, b string) int {
// sadly this []byte will allocate... TODO(miek): check if this is needed // sadly this []byte will allocate... TODO(miek): check if this is needed
// for a name, otherwise compare the strings. // for a name, otherwise compare the strings.
ab := []byte(a[ai:aj]) ab := []byte(strings.ToLower(a[ai:aj]))
bb := []byte(b[bi:bj]) bb := []byte(strings.ToLower(b[bi:bj]))
doDDD(ab) doDDD(ab)
doDDD(bb) doDDD(bb)

View File

@ -73,7 +73,10 @@ func (z *Zone) CopyWithoutApex() *Zone {
// Insert inserts r into z. // Insert inserts r into z.
func (z *Zone) Insert(r dns.RR) error { func (z *Zone) Insert(r dns.RR) error {
r.Header().Name = strings.ToLower(r.Header().Name) // r.Header().Name = strings.ToLower(r.Header().Name)
if r.Header().Rrtype != dns.TypeSRV {
r.Header().Name = strings.ToLower(r.Header().Name)
}
switch h := r.Header().Rrtype; h { switch h := r.Header().Rrtype; h {
case dns.TypeNS: case dns.TypeNS:
@ -108,7 +111,7 @@ func (z *Zone) Insert(r dns.RR) error {
case dns.TypeMX: case dns.TypeMX:
r.(*dns.MX).Mx = strings.ToLower(r.(*dns.MX).Mx) r.(*dns.MX).Mx = strings.ToLower(r.(*dns.MX).Mx)
case dns.TypeSRV: case dns.TypeSRV:
r.(*dns.SRV).Target = strings.ToLower(r.(*dns.SRV).Target) // r.(*dns.SRV).Target = strings.ToLower(r.(*dns.SRV).Target)
} }
z.Tree.Insert(r) z.Tree.Insert(r)

View File

@ -1,6 +1,12 @@
package file package file
import "testing" import (
"testing"
"github.com/coredns/coredns/plugin/file/tree"
"github.com/miekg/dns"
)
func TestNameFromRight(t *testing.T) { func TestNameFromRight(t *testing.T) {
z := NewZone("example.org.", "stdin") z := NewZone("example.org.", "stdin")
@ -28,3 +34,41 @@ func TestNameFromRight(t *testing.T) {
} }
} }
} }
func TestInsertPreservesSRVCase(t *testing.T) {
z := NewZone("home.arpa.", "stdin")
// SRV with mixed case and space-escaped instance name
srv, err := dns.NewRR(`Home\032Media._smb._tcp.home.arpa. 5 IN SRV 0 0 445 samba.home.arpa.`)
if err != nil {
t.Fatalf("Failed to parse SRV RR: %v", err)
}
if err := z.Insert(srv); err != nil {
t.Fatalf("Insert failed: %v", err)
}
found := false
err = z.Walk(func(elem *tree.Elem, rrsets map[uint16][]dns.RR) error {
for _, rrs := range rrsets {
for _, rr := range rrs {
if srvRR, ok := rr.(*dns.SRV); ok {
if srvRR.Hdr.Name == "Home\\032Media._smb._tcp.home.arpa." {
found = true
if srvRR.Target != "samba.home.arpa." {
t.Errorf("Expected SRV target to be 'samba.home.arpa.', got %q", srvRR.Target)
}
}
}
}
}
return nil
})
if err != nil {
t.Fatalf("Tree walk failed: %v", err)
}
if !found {
t.Errorf("SRV record with original case not found in tree")
}
}