Skip to content

Commit

Permalink
Give the service address in SRV lookup when it differs from the node's
Browse files Browse the repository at this point in the history
  • Loading branch information
kyhavlov committed Oct 28, 2016
1 parent 2de81c2 commit 2a26597
Showing 1 changed file with 66 additions and 1 deletion.
67 changes: 66 additions & 1 deletion command/agent/dns.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package agent

import (
"encoding/hex"
"fmt"
"io"
"log"
Expand Down Expand Up @@ -357,6 +358,46 @@ PARSE:
query := strings.Join(labels[:n-1], ".")
d.preparedQueryLookup(network, datacenter, query, req, resp)

case "addr":
if n < 2 {
goto INVALID
}

switch len(labels[0]) / 2 {
// IPv4
case 4:
ip, err := hex.DecodeString(labels[0])
if err != nil {
goto INVALID
}

resp.Answer = append(resp.Answer, &dns.A{
Hdr: dns.RR_Header{
Name: qName + d.domain,
Rrtype: dns.TypeA,
Class: dns.ClassINET,
Ttl: uint32(d.config.NodeTTL / time.Second),
},
A: ip,
})
// IPv6
case 16:
ip, err := hex.DecodeString(labels[0])
if err != nil {
goto INVALID
}

resp.Answer = append(resp.Answer, &dns.AAAA{
Hdr: dns.RR_Header{
Name: qName + d.domain,
Rrtype: dns.TypeAAAA,
Class: dns.ClassINET,
Ttl: uint32(d.config.NodeTTL / time.Second),
},
AAAA: ip,
})
}

default:
// Store the DC, and re-parse
datacenter = labels[n-1]
Expand Down Expand Up @@ -820,8 +861,32 @@ func (d *DNSServer) serviceSRVRecords(dc string, nodes structs.CheckServiceNodes

// Add the extra record
records := d.formatNodeRecord(node.Node, addr, srvRec.Target, dns.TypeANY, ttl)

if records != nil {
resp.Extra = append(resp.Extra, records...)
// Use the node address if it doesn't differ from the service address
if addr == node.Node.Address {
resp.Extra = append(resp.Extra, records...)
} else {
// If it differs from the service address, give a special response in the
// 'addr.consul' domain with the service IP encoded in it. We have to do
// this because we can't put an IP in the target field of an SRV record.
switch record := records[0].(type) {
// IPv4
case *dns.A:
addr := hex.EncodeToString(record.A)

// Take the last 8 chars (4 bytes) of the encoded address to avoid junk bytes
srvRec.Target = fmt.Sprintf("%s.addr.%s.%s", addr[len(addr)-(net.IPv4len*2):], dc, d.domain)
record.Hdr.Name = srvRec.Target
resp.Extra = append(resp.Extra, record)

// IPv6
case *dns.AAAA:
srvRec.Target = fmt.Sprintf("%s.addr.%s.%s", hex.EncodeToString(record.AAAA), dc, d.domain)
record.Hdr.Name = srvRec.Target
resp.Extra = append(resp.Extra, record)
}
}
}
}
}
Expand Down

0 comments on commit 2a26597

Please sign in to comment.