68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/miekg/dns"
|
||
|
)
|
||
|
|
||
|
func init() {
|
||
|
dns.HandleFunc(BASE_DOMAIN, serve)
|
||
|
}
|
||
|
|
||
|
func q_String(q dns.Question) string {
|
||
|
return "" + dns.ClassToString[q.Qclass] + " " + dns.TypeToString[q.Qtype] + " " + q.Name
|
||
|
}
|
||
|
|
||
|
func serve(w dns.ResponseWriter, r *dns.Msg) {
|
||
|
qStr := ""
|
||
|
for _, q := range r.Question {
|
||
|
qStr += "\n" + q_String(q)
|
||
|
}
|
||
|
fmt.Printf("got question from %s:%s\n", w.RemoteAddr().String(), qStr)
|
||
|
|
||
|
m := new(dns.Msg)
|
||
|
defer w.WriteMsg(m)
|
||
|
|
||
|
if r.Opcode != dns.OpcodeQuery && len(r.Question) != 1 {
|
||
|
m.SetRcode(r, dns.RcodeRefused)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
q := r.Question[0]
|
||
|
qName := strings.ToLower(q.Name)
|
||
|
qKey := qName[0 : len(q.Name)-len(BASE_DOMAIN)]
|
||
|
|
||
|
m.SetReply(r)
|
||
|
m.Authoritative = true
|
||
|
m.Compress = false
|
||
|
soa := fmt.Sprintf("%s IN SOA %s hostmaster.%s %d 5 1 1 5", qName, DNS_SERVER, DNS_SERVER, (time.Now().Unix() % 4294967295))
|
||
|
if soaRR, err := dns.NewRR(soa); err == nil {
|
||
|
m.Ns = append(m.Answer, soaRR)
|
||
|
}
|
||
|
|
||
|
if q.Qtype == dns.TypeTXT {
|
||
|
for _, rData := range db.Lookup(qKey) {
|
||
|
if rr, err := dns.NewRR(fmt.Sprintf("$TTL 5\n%s TXT %s", qName, rData)); err == nil {
|
||
|
m.Answer = append(m.Answer, rr)
|
||
|
} else {
|
||
|
fmt.Printf("error building rr: %s\n", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
rrStr := ""
|
||
|
for _, rr := range m.Answer {
|
||
|
rrStr += "\n" + rr.String()
|
||
|
}
|
||
|
fmt.Printf("sending response for %s:%s\n", qName, rrStr)
|
||
|
return
|
||
|
} else {
|
||
|
fmt.Printf("no records for name %s\n", qName)
|
||
|
}
|
||
|
|
||
|
m.SetRcode(r, dns.RcodeNameError)
|
||
|
fmt.Printf("%s\n", m.String())
|
||
|
}
|