diff options
Diffstat (limited to 'plugin/file/dname.go')
-rw-r--r-- | plugin/file/dname.go | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/plugin/file/dname.go b/plugin/file/dname.go new file mode 100644 index 000000000..f552bfdfd --- /dev/null +++ b/plugin/file/dname.go @@ -0,0 +1,44 @@ +package file + +import ( + "github.com/coredns/coredns/plugin/pkg/dnsutil" + + "github.com/miekg/dns" +) + +// substituteDNAME performs the DNAME substitution defined by RFC 6672, +// assuming the QTYPE of the query is not DNAME. It returns an empty +// string if there is no match. +func substituteDNAME(qname, owner, target string) string { + if dns.IsSubDomain(owner, qname) && qname != owner { + labels := dns.SplitDomainName(qname) + labels = append(labels[0:len(labels)-dns.CountLabel(owner)], dns.SplitDomainName(target)...) + + return dnsutil.Join(labels) + } + + return "" +} + +// synthesizeCNAME returns a CNAME RR pointing to the resulting name of +// the DNAME substitution. The owner name of the CNAME is the QNAME of +// the query and the TTL is the same as the corresponding DNAME RR. +// +// It returns nil if the DNAME substitution has no match. +func synthesizeCNAME(qname string, d *dns.DNAME) *dns.CNAME { + target := substituteDNAME(qname, d.Header().Name, d.Target) + if target == "" { + return nil + } + + r := new(dns.CNAME) + r.Hdr = dns.RR_Header{ + Name: qname, + Rrtype: dns.TypeCNAME, + Class: dns.ClassINET, + Ttl: d.Header().Ttl, + } + r.Target = target + + return r +} |