agent: Improve DNS parser. Fixes #39.
This commit is contained in:
parent
48ce8e3e86
commit
c7605f070d
|
@ -254,31 +254,40 @@ func (d *DNSServer) dispatch(network string, req, resp *dns.Msg) {
|
|||
|
||||
// The last label is either "node", "service" or a datacenter name
|
||||
PARSE:
|
||||
if len(labels) == 0 {
|
||||
n := len(labels)
|
||||
if n == 0 {
|
||||
goto INVALID
|
||||
}
|
||||
switch labels[len(labels)-1] {
|
||||
switch labels[n-1] {
|
||||
case "service":
|
||||
// Handle lookup with and without tag
|
||||
switch len(labels) {
|
||||
case 2:
|
||||
d.serviceLookup(network, datacenter, labels[0], "", req, resp)
|
||||
case 3:
|
||||
d.serviceLookup(network, datacenter, labels[1], labels[0], req, resp)
|
||||
default:
|
||||
if n == 1 {
|
||||
goto INVALID
|
||||
}
|
||||
|
||||
// Extract the service
|
||||
service := labels[n-2]
|
||||
|
||||
// Support "." in the label, re-join all the parts
|
||||
tag := ""
|
||||
if n >= 3 {
|
||||
tag = strings.Join(labels[:n-2], ".")
|
||||
}
|
||||
|
||||
// Handle lookup with and without tag
|
||||
d.serviceLookup(network, datacenter, service, tag, req, resp)
|
||||
|
||||
case "node":
|
||||
if len(labels) != 2 {
|
||||
if len(labels) == 1 {
|
||||
goto INVALID
|
||||
}
|
||||
d.nodeLookup(network, datacenter, labels[0], req, resp)
|
||||
// Allow a "." in the node name, just join all the parts
|
||||
node := strings.Join(labels[:n-1], ".")
|
||||
d.nodeLookup(network, datacenter, node, req, resp)
|
||||
|
||||
default:
|
||||
// Store the DC, and re-parse
|
||||
datacenter = labels[len(labels)-1]
|
||||
labels = labels[:len(labels)-1]
|
||||
datacenter = labels[n-1]
|
||||
labels = labels[:n-1]
|
||||
goto PARSE
|
||||
}
|
||||
return
|
||||
|
|
|
@ -124,6 +124,48 @@ func TestDNS_NodeLookup(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDNS_NodeLookup_PeriodName(t *testing.T) {
|
||||
dir, srv := makeDNSServer(t)
|
||||
defer os.RemoveAll(dir)
|
||||
defer srv.agent.Shutdown()
|
||||
|
||||
// Wait for leader
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// Register node with period in name
|
||||
args := &structs.RegisterRequest{
|
||||
Datacenter: "dc1",
|
||||
Node: "foo.bar",
|
||||
Address: "127.0.0.1",
|
||||
}
|
||||
var out struct{}
|
||||
if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("foo.bar.node.consul.", dns.TypeANY)
|
||||
|
||||
c := new(dns.Client)
|
||||
addr, _ := srv.agent.config.ClientListener(srv.agent.config.Ports.DNS)
|
||||
in, _, err := c.Exchange(m, addr.String())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if len(in.Answer) != 1 {
|
||||
t.Fatalf("Bad: %#v", in)
|
||||
}
|
||||
|
||||
aRec, ok := in.Answer[0].(*dns.A)
|
||||
if !ok {
|
||||
t.Fatalf("Bad: %#v", in.Answer[0])
|
||||
}
|
||||
if aRec.A.String() != "127.0.0.1" {
|
||||
t.Fatalf("Bad: %#v", in.Answer[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNS_NodeLookup_AAAA(t *testing.T) {
|
||||
dir, srv := makeDNSServer(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
@ -270,6 +312,67 @@ func TestDNS_ServiceLookup(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDNS_ServiceLookup_TagPeriod(t *testing.T) {
|
||||
dir, srv := makeDNSServer(t)
|
||||
defer os.RemoveAll(dir)
|
||||
defer srv.agent.Shutdown()
|
||||
|
||||
// Wait for leader
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// Register node
|
||||
args := &structs.RegisterRequest{
|
||||
Datacenter: "dc1",
|
||||
Node: "foo",
|
||||
Address: "127.0.0.1",
|
||||
Service: &structs.NodeService{
|
||||
Service: "db",
|
||||
Tags: []string{"v1.master"},
|
||||
Port: 12345,
|
||||
},
|
||||
}
|
||||
var out struct{}
|
||||
if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("v1.master.db.service.consul.", dns.TypeSRV)
|
||||
|
||||
c := new(dns.Client)
|
||||
addr, _ := srv.agent.config.ClientListener(srv.agent.config.Ports.DNS)
|
||||
in, _, err := c.Exchange(m, addr.String())
|
||||
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 != "foo.node.dc1.consul." {
|
||||
t.Fatalf("Bad: %#v", srvRec)
|
||||
}
|
||||
|
||||
aRec, ok := in.Extra[0].(*dns.A)
|
||||
if !ok {
|
||||
t.Fatalf("Bad: %#v", in.Extra[0])
|
||||
}
|
||||
if aRec.Hdr.Name != "foo.node.dc1.consul." {
|
||||
t.Fatalf("Bad: %#v", in.Extra[0])
|
||||
}
|
||||
if aRec.A.String() != "127.0.0.1" {
|
||||
t.Fatalf("Bad: %#v", in.Extra[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNS_ServiceLookup_Dedup(t *testing.T) {
|
||||
dir, srv := makeDNSServer(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
|
Loading…
Reference in New Issue