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()) }