From be14f6da9026f778aa59b94d8e0a72e25766a0a9 Mon Sep 17 00:00:00 2001 From: Konstantine Date: Sun, 17 Oct 2021 15:02:13 +0300 Subject: [PATCH] fix altDomain responses for services where address is IP, added tests --- agent/dns.go | 7 +++- agent/dns_test.go | 104 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/agent/dns.go b/agent/dns.go index c003305a4..b836c7eec 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -678,6 +678,9 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi // have to deref to clone it so we don't modify (start from the agent's defaults) var entMeta = d.defaultEnterpriseMeta + // Choose correct response domain + respDomain := d.getResponseDomain(req.Question[0].Name) + // Get the QName without the domain suffix qName := strings.ToLower(dns.Fqdn(req.Question[0].Name)) qName = d.trimDomain(qName) @@ -849,7 +852,7 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi //check if the query type is A for IPv4 or ANY aRecord := &dns.A{ Hdr: dns.RR_Header{ - Name: qName + d.domain, + Name: qName + respDomain, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: uint32(cfg.NodeTTL / time.Second), @@ -870,7 +873,7 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi //check if the query type is AAAA for IPv6 or ANY aaaaRecord := &dns.AAAA{ Hdr: dns.RR_Header{ - Name: qName + d.domain, + Name: qName + respDomain, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: uint32(cfg.NodeTTL / time.Second), diff --git a/agent/dns_test.go b/agent/dns_test.go index e658c58f4..6bab31d36 100644 --- a/agent/dns_test.go +++ b/agent/dns_test.go @@ -2814,6 +2814,110 @@ func TestDNS_ServiceLookup_ServiceAddressIPV6(t *testing.T) { } } +func TestDNS_AltDomain_ServiceLookup_ServiceAddressIPV6(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + t.Parallel() + a := NewTestAgent(t, ` + alt_domain = "test-domain" + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Address: "2607:20:4005:808::200e", + Port: 12345, + }, + } + + var out struct{} + if err := a.RPC("Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC("PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly and via prepared query. + questions := []struct { + ask string + want string + }{ + {"db.service.consul.", "2607002040050808000000000000200e.addr.dc1.consul."}, + {"db.service.test-domain.", "2607002040050808000000000000200e.addr.dc1.test-domain."}, + {id + ".query.consul.", "2607002040050808000000000000200e.addr.dc1.consul."}, + {id + ".query.test-domain.", "2607002040050808000000000000200e.addr.dc1.test-domain."}, + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question.ask, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } + + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != question.want { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + + aRec, ok := in.Extra[0].(*dns.AAAA) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != question.want { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.AAAA.String() != "2607:20:4005:808::200e" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + } +} + func TestDNS_ServiceLookup_WanTranslation(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short")