diff --git a/cmd/pancheri/main.go b/cmd/pancheri/main.go index feb982f..63266ff 100644 --- a/cmd/pancheri/main.go +++ b/cmd/pancheri/main.go @@ -44,9 +44,23 @@ func main() { }).Info("enabling upstream resolver") r = pancheri.NewResolver(c.Resolver.Upstream) - err = r.Resolve("example.com", dns.TypeA) - if err != nil { - logrus.Errorf("failed to resolve: %s", err) - } + } + + handler := pancheri.Handler{ + C: c, + R: r, + } + server := &dns.Server{ + Addr: c.Server.Host + ":" + c.Server.Port, + Net: "udp", + Handler: &handler, + UDPSize: 65535, + ReusePort: true, + } + err = server.ListenAndServe() + + if err != nil { + logrus.Errorf("failed to start server: %s", err) + os.Exit(1) } } diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..545ced1 --- /dev/null +++ b/handler.go @@ -0,0 +1,57 @@ +package pancheri + +import ( + "github.com/miekg/dns" + "github.com/sirupsen/logrus" +) + +type Handler struct { + C *Config + R *Resolver +} + +func (h *Handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { + + // figure out how we should resolve this + + // is this in our list of authoritative domains? + // TODO + + // okay, do we have upstream resolution enabled? + if h.C.Resolver.Enable { + // alright, resolve it with the resolver + msg := new(dns.Msg) + msg.SetReply(r) + msg.Authoritative = true + + for _, question := range r.Question { + answers, err := h.R.Resolve(question.Name, question.Qtype) + if err != nil { + logrus.Errorf("error resolving: %s", err) + return + } + msg.Answer = append(msg.Answer, answers...) + } + + err := w.WriteMsg(msg) + if err != nil { + logrus.Errorf("error responding: %s", err) + return + } + } else { + // alright, send an nxdomain + msg := new(dns.Msg) + msg.SetReply(r) + msg.Authoritative = true + if r.RecursionDesired { + msg.RecursionAvailable = true + } + msg.Rcode = dns.RcodeNameError + + err := w.WriteMsg(msg) + if err != nil { + logrus.Errorf("error responding: %s", err) + return + } + } +} diff --git a/resolver.go b/resolver.go index fe21a34..a4fe510 100644 --- a/resolver.go +++ b/resolver.go @@ -17,7 +17,7 @@ func NewResolver(upstream string) *Resolver { } } -func (r *Resolver) Resolve(domain string, qtype uint16) error { +func (r *Resolver) Resolve(domain string, qtype uint16) ([]dns.RR, error) { logrus.WithFields(logrus.Fields{ "domain": domain, "qtype": qtype, @@ -30,12 +30,8 @@ func (r *Resolver) Resolve(domain string, qtype uint16) error { in, _, err := r.client.Exchange(m, r.upstream) if err != nil { - return err + return nil, err } - for _, ans := range in.Answer { - logrus.Debug(ans) - } - - return nil + return in.Answer, nil }