Resolve TXT records via CNAME (#3557)

* Add test case for TXT lookup via CNAME

Signed-off-by: Jonathan Nagy <nagytech@users.noreply.github.com>

* Return HostType of explicit TXT records

Signed-off-by: Jonathan Nagy <nagytech@users.noreply.github.com>

* Adapt TXT method lookup to allow lookup via CNAME

Signed-off-by: Jonathan Nagy <nagytech@users.noreply.github.com>

* Implement lookup of TXT records via CNAME

Signed-off-by: Jonathan Nagy <nagytech@users.noreply.github.com>
This commit is contained in:
Jonathan Nagy
2020-01-04 00:16:04 +11:00
committed by Miek Gieben
parent acac649c1b
commit e3266d24f7
6 changed files with 80 additions and 12 deletions

View File

@@ -325,15 +325,69 @@ func CNAME(ctx context.Context, b ServiceBackend, zone string, state request.Req
}
// TXT returns TXT records from Backend or an error.
func TXT(ctx context.Context, b ServiceBackend, zone string, state request.Request, opt Options) (records []dns.RR, err error) {
services, err := b.Services(ctx, state, false, opt)
func TXT(ctx context.Context, b ServiceBackend, zone string, state request.Request, previousRecords []dns.RR, opt Options) (records []dns.RR, err error) {
services, err := b.Services(ctx, state, true, opt)
if err != nil {
return nil, err
}
dup := make(map[string]struct{})
for _, serv := range services {
records = append(records, serv.NewTXT(state.QName()))
what, _ := serv.HostType()
switch what {
case dns.TypeCNAME:
if Name(state.Name()).Matches(dns.Fqdn(serv.Host)) {
// x CNAME x is a direct loop, don't add those
continue
}
newRecord := serv.NewCNAME(state.QName(), serv.Host)
if len(previousRecords) > 7 {
// don't add it, and just continue
continue
}
if dnsutil.DuplicateCNAME(newRecord, previousRecords) {
continue
}
if dns.IsSubDomain(zone, dns.Fqdn(serv.Host)) {
state1 := state.NewWithQuestion(serv.Host, state.QType())
state1.Zone = zone
nextRecords, err := TXT(ctx, b, zone, state1, append(previousRecords, newRecord), opt)
if err == nil {
// Not only have we found something we should add the CNAME and the IP addresses.
if len(nextRecords) > 0 {
records = append(records, newRecord)
records = append(records, nextRecords...)
}
}
continue
}
// This means we can not complete the CNAME, try to look else where.
target := newRecord.Target
// Lookup
m1, e1 := b.Lookup(ctx, state, target, state.QType())
if e1 != nil {
continue
}
// Len(m1.Answer) > 0 here is well?
records = append(records, newRecord)
records = append(records, m1.Answer...)
continue
case dns.TypeTXT:
if _, ok := dup[serv.Host]; !ok {
dup[serv.Host] = struct{}{}
return append(records, serv.NewTXT(state.QName())), nil
}
}
}
return records, nil
}