diff --git a/internal/authoritative.go b/internal/authoritative.go index 1e0a313..cb6fcc8 100644 --- a/internal/authoritative.go +++ b/internal/authoritative.go @@ -6,6 +6,8 @@ import ( "github.com/miekg/dns" ) +type rrMap map[uint16]map[string][]dns.RR + // All record types to send when a ANY request is send var anyRecordTypes = []uint16{ dns.TypeSOA, @@ -43,8 +45,9 @@ func handleRequest(w dns.ResponseWriter, r *dns.Msg, zone zoneView) { // Handle any other type m.Answer = append(m.Answer, rrs[q.Name]...) - // Check for wildcard + // if no rr found yet if len(m.Answer) == 0 { + // Check for wildcard parts := dns.SplitDomainName(q.Name)[1:] searchDomain := "*." + dns.Fqdn(strings.Join(parts, ".")) foundDomain := rrs[searchDomain] @@ -80,6 +83,23 @@ func handleRequest(w dns.ResponseWriter, r *dns.Msg, zone zoneView) { m.Answer = append(m.Answer, zone.rr[q.Qtype][t.Target]...) } } + } else { + // No direct A/AAAA or CNAME found. Check for CNAME wildcard + parts := dns.SplitDomainName(q.Name)[1:] + searchDomain := "*." + dns.Fqdn(strings.Join(parts, ".")) + foundDomain := zone.rr[dns.TypeCNAME][searchDomain] + for _, rr := range foundDomain { + // Add CNAME to answer section + newRR := rr + newRR.Header().Name = q.Name + m.Answer = append(m.Answer, newRR) + + // Add resolved CNAME to *also* to the answer section (bind does the same soo) + if t, ok := rr.(*dns.CNAME); ok { + m.Answer = append(m.Answer, zone.rr[dns.TypeA][t.Target]...) + m.Answer = append(m.Answer, zone.rr[dns.TypeAAAA][t.Target]...) + } + } } } case dns.TypeNS: diff --git a/internal/cooldns.go b/internal/cooldns.go index 46ec9f3..cebf855 100644 --- a/internal/cooldns.go +++ b/internal/cooldns.go @@ -16,8 +16,6 @@ type zoneView struct { type zoneMap map[string][]zoneView -type rrMap map[uint16]map[string][]dns.RR - // Start starts cooldns func Start(configPath string) { config, err := loadConfig(configPath)