diff --git a/libnetwork/network.go b/libnetwork/network.go index f128cac785..b08916303b 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -1381,14 +1381,18 @@ func delIPToName(ipMap setmatrix.SetMatrix, name, serviceID string, ip net.IP) { } func addNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) { - svcMap.Insert(name, svcMapEntry{ + // Since DNS name resolution is case-insensitive, Use the lower-case form + // of the name as the key into svcMap + lowerCaseName := strings.ToLower(name) + svcMap.Insert(lowerCaseName, svcMapEntry{ ip: epIP.String(), serviceID: serviceID, }) } func delNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) { - svcMap.Remove(name, svcMapEntry{ + lowerCaseName := strings.ToLower(name) + svcMap.Remove(lowerCaseName, svcMapEntry{ ip: epIP.String(), serviceID: serviceID, }) @@ -1956,6 +1960,7 @@ func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) { } req = strings.TrimSuffix(req, ".") + req = strings.ToLower(req) ipSet, ok := sr.svcMap.Get(req) if ipType == types.IPv6 { diff --git a/libnetwork/resolver.go b/libnetwork/resolver.go index 4f5f71897c..8e3158e559 100644 --- a/libnetwork/resolver.go +++ b/libnetwork/resolver.go @@ -366,8 +366,8 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { if query == nil || len(query.Question) == 0 { return } - name := query.Question[0].Name + name := query.Question[0].Name switch query.Question[0].Qtype { case dns.TypeA: resp, err = r.handleIPQuery(name, query, types.IPv4) diff --git a/libnetwork/resolver_test.go b/libnetwork/resolver_test.go index 8e5755bccb..970255f984 100644 --- a/libnetwork/resolver_test.go +++ b/libnetwork/resolver_test.go @@ -126,29 +126,33 @@ func TestDNSIPQuery(t *testing.T) { r := NewResolver(resolverIPSandbox, false, sb.Key(), sb.(*sandbox)) // test name1's IP is resolved correctly with the default A type query - q := new(dns.Msg) - q.SetQuestion("name1", dns.TypeA) - r.(*resolver).ServeDNS(w, q) - resp := w.GetResponse() - checkNonNullResponse(t, resp) - t.Log("Response: ", resp.String()) - checkDNSResponseCode(t, resp, dns.RcodeSuccess) - checkDNSAnswersCount(t, resp, 1) - checkDNSRRType(t, resp.Answer[0].Header().Rrtype, dns.TypeA) - if answer, ok := resp.Answer[0].(*dns.A); ok { - if !bytes.Equal(answer.A, net.ParseIP("192.168.0.1")) { - t.Fatalf("IP response in Answer %v does not match 192.168.0.1", answer.A) + // Also make sure DNS lookups are case insensitive + names := []string{"name1", "NaMe1"} + for _, name := range names { + q := new(dns.Msg) + q.SetQuestion(name, dns.TypeA) + r.(*resolver).ServeDNS(w, q) + resp := w.GetResponse() + checkNonNullResponse(t, resp) + t.Log("Response: ", resp.String()) + checkDNSResponseCode(t, resp, dns.RcodeSuccess) + checkDNSAnswersCount(t, resp, 1) + checkDNSRRType(t, resp.Answer[0].Header().Rrtype, dns.TypeA) + if answer, ok := resp.Answer[0].(*dns.A); ok { + if !bytes.Equal(answer.A, net.ParseIP("192.168.0.1")) { + t.Fatalf("IP response in Answer %v does not match 192.168.0.1", answer.A) + } + } else { + t.Fatal("Answer of type A not found") } - } else { - t.Fatal("Answer of type A not found") + w.ClearResponse() } - w.ClearResponse() // test MX query with name1 results in Success response with 0 answer records - q = new(dns.Msg) + q := new(dns.Msg) q.SetQuestion("name1", dns.TypeMX) r.(*resolver).ServeDNS(w, q) - resp = w.GetResponse() + resp := w.GetResponse() checkNonNullResponse(t, resp) t.Log("Response: ", resp.String()) checkDNSResponseCode(t, resp, dns.RcodeSuccess)