acme-dns/dns.go

111 lines
3.0 KiB
Go
Raw Normal View History

2016-11-11 21:48:00 +07:00
package main
import (
"fmt"
"github.com/miekg/dns"
log "github.com/sirupsen/logrus"
2016-11-14 01:35:11 +07:00
"strings"
2016-11-11 21:48:00 +07:00
"time"
)
func readQuery(m *dns.Msg) {
for _, que := range m.Question {
if rr, rc, err := answer(que); err == nil {
m.MsgHdr.Rcode = rc
for _, r := range rr {
m.Answer = append(m.Answer, r)
}
}
}
}
func answerTXT(q dns.Question) ([]dns.RR, int, error) {
var ra []dns.RR
2016-11-28 00:41:54 +07:00
rcode := dns.RcodeNameError
subdomain := sanitizeDomainQuestion(q.Name)
atxt, err := DB.GetTXTForDomain(subdomain)
2016-11-11 21:48:00 +07:00
if err != nil {
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"error": err.Error()}).Debug("Error while trying to get record")
2016-11-11 21:48:00 +07:00
return ra, dns.RcodeNameError, err
}
for _, v := range atxt {
if len(v) > 0 {
2016-11-11 21:48:00 +07:00
r := new(dns.TXT)
2016-11-28 00:41:54 +07:00
r.Hdr = dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 1}
r.Txt = append(r.Txt, v)
2016-11-11 21:48:00 +07:00
ra = append(ra, r)
rcode = dns.RcodeSuccess
}
}
2016-11-26 20:42:35 +07:00
2016-11-28 00:41:54 +07:00
log.WithFields(log.Fields{"domain": q.Name}).Info("Answering TXT question for domain")
2016-11-11 21:48:00 +07:00
return ra, rcode, nil
}
func answer(q dns.Question) ([]dns.RR, int, error) {
if q.Qtype == dns.TypeTXT {
return answerTXT(q)
}
var r []dns.RR
2016-11-23 23:07:38 +07:00
var rcode = dns.RcodeSuccess
2016-11-17 00:15:36 +07:00
var domain = strings.ToLower(q.Name)
2016-11-23 23:07:38 +07:00
var rtype = q.Qtype
2016-11-11 21:48:00 +07:00
r, ok := RR.Records[rtype][domain]
if !ok {
r, ok = RR.Records[dns.TypeCNAME][domain]
if !ok {
rcode = dns.RcodeNameError
}
2016-11-11 21:48:00 +07:00
}
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"qtype": dns.TypeToString[rtype], "domain": domain, "rcode": dns.RcodeToString[rcode]}).Debug("Answering question for domain")
2016-11-11 21:48:00 +07:00
return r, rcode, nil
}
func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
m := new(dns.Msg)
m.SetReply(r)
if r.Opcode == dns.OpcodeQuery {
readQuery(m)
}
w.WriteMsg(m)
}
// Parse config records
func (r *Records) Parse(config general) {
2016-11-11 21:48:00 +07:00
rrmap := make(map[uint16]map[string][]dns.RR)
for _, v := range config.StaticRecords {
2016-11-14 01:35:11 +07:00
rr, err := dns.NewRR(strings.ToLower(v))
2016-11-11 21:48:00 +07:00
if err != nil {
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"error": err.Error(), "rr": v}).Warning("Could not parse RR from config")
2016-11-11 21:48:00 +07:00
continue
}
// Add parsed RR to the list
2016-11-23 23:07:38 +07:00
rrmap = appendRR(rrmap, rr)
2016-11-11 21:48:00 +07:00
}
// Create serial
serial := time.Now().Format("2006010215")
// Add SOA
SOAstring := fmt.Sprintf("%s. SOA %s. %s. %s 28800 7200 604800 86400", strings.ToLower(config.Domain), strings.ToLower(config.Nsname), strings.ToLower(config.Nsadmin), serial)
2016-11-11 21:48:00 +07:00
soarr, err := dns.NewRR(SOAstring)
if err != nil {
2016-11-28 21:25:42 +07:00
log.WithFields(log.Fields{"error": err.Error(), "soa": SOAstring}).Error("Error while adding SOA record")
2016-11-11 21:48:00 +07:00
} else {
2016-11-23 23:07:38 +07:00
rrmap = appendRR(rrmap, soarr)
2016-11-11 21:48:00 +07:00
}
r.Records = rrmap
}
2016-11-23 23:07:38 +07:00
func appendRR(rrmap map[uint16]map[string][]dns.RR, rr dns.RR) map[uint16]map[string][]dns.RR {
2016-11-11 21:48:00 +07:00
_, ok := rrmap[rr.Header().Rrtype]
if !ok {
newrr := make(map[string][]dns.RR)
rrmap[rr.Header().Rrtype] = newrr
}
rrmap[rr.Header().Rrtype][rr.Header().Name] = append(rrmap[rr.Header().Rrtype][rr.Header().Name], rr)
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"recordtype": dns.TypeToString[rr.Header().Rrtype], "domain": rr.Header().Name}).Debug("Adding new record type to domain")
2016-11-11 21:48:00 +07:00
return rrmap
}