diff --git a/client/internal/dns/local/local.go b/client/internal/dns/local/local.go index ae27b3b56..cbdc64997 100644 --- a/client/internal/dns/local/local.go +++ b/client/internal/dns/local/local.go @@ -201,9 +201,13 @@ func (d *Resolver) lookupRecords(logger *log.Entry, question dns.Question) looku records, found := d.records[question] usingWildcard := false wildQuestion := transformToWildcard(question) + // RFC 4592 section 2.2.1: wildcard only matches if the name does NOT exist in the zone. + // If the domain exists with any record type, return NODATA instead of wildcard match. if !found && supportsWildcard(question.Qtype) { - records, found = d.records[wildQuestion] - usingWildcard = found + if _, domainExists := d.domains[domain.Domain(question.Name)]; !domainExists { + records, found = d.records[wildQuestion] + usingWildcard = found + } } if !found { diff --git a/client/internal/dns/local/local_test.go b/client/internal/dns/local/local_test.go index dc295cd17..73f70035f 100644 --- a/client/internal/dns/local/local_test.go +++ b/client/internal/dns/local/local_test.go @@ -2506,8 +2506,10 @@ func TestLocalResolver_MixedRecordTypes(t *testing.T) { resolver.ServeDNS(&test.MockResponseWriter{WriteMsgFunc: func(m *dns.Msg) error { respAAAA = m; return nil }}, msgAAAA) require.NotNil(t, respAAAA) - // host.example.com exists (has A), so AAAA query returns NODATA, not wildcard + // RFC 4592 section 2.2.1: wildcard should NOT match when the name EXISTS in zone. + // host.example.com exists (has A record), so AAAA query returns NODATA, not wildcard. assert.Equal(t, dns.RcodeSuccess, respAAAA.Rcode, "Should return NODATA for existing host without AAAA") + assert.Len(t, respAAAA.Answer, 0, "RFC 4592: wildcard should not match when name exists") // AAAA query for other host should return wildcard AAAA msgAAAAOther := new(dns.Msg).SetQuestion("other.example.com.", dns.TypeAAAA)