mirror of https://github.com/status-im/consul.git
agent: Improve DNS parser. Fixes #39.
This commit is contained in:
parent
00bedd4020
commit
c1bd7169f5
|
@ -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
|
// The last label is either "node", "service" or a datacenter name
|
||||||
PARSE:
|
PARSE:
|
||||||
if len(labels) == 0 {
|
n := len(labels)
|
||||||
|
if n == 0 {
|
||||||
goto INVALID
|
goto INVALID
|
||||||
}
|
}
|
||||||
switch labels[len(labels)-1] {
|
switch labels[n-1] {
|
||||||
case "service":
|
case "service":
|
||||||
// Handle lookup with and without tag
|
if n == 1 {
|
||||||
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:
|
|
||||||
goto INVALID
|
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":
|
case "node":
|
||||||
if len(labels) != 2 {
|
if len(labels) == 1 {
|
||||||
goto INVALID
|
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:
|
default:
|
||||||
// Store the DC, and re-parse
|
// Store the DC, and re-parse
|
||||||
datacenter = labels[len(labels)-1]
|
datacenter = labels[n-1]
|
||||||
labels = labels[:len(labels)-1]
|
labels = labels[:n-1]
|
||||||
goto PARSE
|
goto PARSE
|
||||||
}
|
}
|
||||||
return
|
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) {
|
func TestDNS_NodeLookup_AAAA(t *testing.T) {
|
||||||
dir, srv := makeDNSServer(t)
|
dir, srv := makeDNSServer(t)
|
||||||
defer os.RemoveAll(dir)
|
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) {
|
func TestDNS_ServiceLookup_Dedup(t *testing.T) {
|
||||||
dir, srv := makeDNSServer(t)
|
dir, srv := makeDNSServer(t)
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
Loading…
Reference in New Issue