From f7fcb030043c9845b9679279c78705e0e4e7a046 Mon Sep 17 00:00:00 2001 From: James Phillips Date: Fri, 12 Aug 2016 12:16:21 -0700 Subject: [PATCH] Makes name compares case-insensitive. --- command/agent/dns.go | 14 ++++++++---- command/agent/dns_test.go | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/command/agent/dns.go b/command/agent/dns.go index b2c72f5309..f5f8521679 100644 --- a/command/agent/dns.go +++ b/command/agent/dns.go @@ -494,11 +494,13 @@ func (d *DNSServer) formatNodeRecord(node *structs.Node, addr, qName string, qTy return records } -// indexRRs creates a map which indexes a given list of RRs by name. +// indexRRs creates a map which indexes a given list of RRs by name. NOTE that +// the names are all squashed to lower case so we can perform case-insensitive +// lookups; the RRs are not modified. func indexRRs(rrs []dns.RR) map[string]dns.RR { index := make(map[string]dns.RR, len(rrs)) for _, rr := range rrs { - name := rr.Header().Name + name := strings.ToLower(rr.Header().Name) if _, ok := index[name]; !ok { index[name] = rr } @@ -519,7 +521,11 @@ func syncExtra(index map[string]dns.RR, resp *dns.Msg) { if !ok { continue } - target := srv.Target + + // Note that we always use lower case when using the index so + // that compares are not case-sensitive. We don't alter the actual + // RRs we add into the extra section, however. + target := strings.ToLower(srv.Target) RESOLVE: if _, ok := resolved[target]; ok { @@ -531,7 +537,7 @@ func syncExtra(index map[string]dns.RR, resp *dns.Msg) { if ok { extra = append(extra, extraRR) if cname, ok := extraRR.(*dns.CNAME); ok { - target = cname.Target + target = strings.ToLower(cname.Target) goto RESOLVE } } diff --git a/command/agent/dns_test.go b/command/agent/dns_test.go index 78f966aaba..073ba23a10 100644 --- a/command/agent/dns_test.go +++ b/command/agent/dns_test.go @@ -3403,6 +3403,19 @@ func TestDNS_syncExtra(t *testing.T) { Port: 1003, Target: "demo.consul.io.", }, + // This one isn't in the Consul domain and it will get + // a CNAME and A record from a recursor that alters the + // case of the name. This proves we look up in the index + // in a case-insensitive way. + &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Port: 1001, + Target: "insensitive.consul.io.", + }, // This is also a CNAME, but it'll be set up to loop to // make sure we don't crash. &dns.SRV{ @@ -3462,6 +3475,23 @@ func TestDNS_syncExtra(t *testing.T) { }, Target: "fakeserver.consul.io.", }, + // These differ in case to test case insensitivity. + &dns.CNAME{ + Hdr: dns.RR_Header{ + Name: "INSENSITIVE.CONSUL.IO.", + Rrtype: dns.TypeCNAME, + Class: dns.ClassINET, + }, + Target: "Another.Server.Com.", + }, + &dns.A{ + Hdr: dns.RR_Header{ + Name: "another.server.com.", + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP("127.0.0.1"), + }, // This doesn't appear in the answer, so should get // dropped. &dns.A{ @@ -3522,6 +3552,22 @@ func TestDNS_syncExtra(t *testing.T) { }, A: net.ParseIP("127.0.0.1"), }, + &dns.CNAME{ + Hdr: dns.RR_Header{ + Name: "INSENSITIVE.CONSUL.IO.", + Rrtype: dns.TypeCNAME, + Class: dns.ClassINET, + }, + Target: "Another.Server.Com.", + }, + &dns.A{ + Hdr: dns.RR_Header{ + Name: "another.server.com.", + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP("127.0.0.1"), + }, &dns.CNAME{ Hdr: dns.RR_Header{ Name: "deadly.consul.io.",