diff --git a/authority.go b/authority.go new file mode 100644 index 0000000..f6e85ab --- /dev/null +++ b/authority.go @@ -0,0 +1,5 @@ +package pancheri + +type Authority struct { + Zones map[string]*Zone +} diff --git a/cmd/pancheri/main.go b/cmd/pancheri/main.go index e88296b..0e03f48 100644 --- a/cmd/pancheri/main.go +++ b/cmd/pancheri/main.go @@ -31,15 +31,23 @@ func main() { } logrus.SetLevel(c.Logging.Level) + zones := make(map[string]*pancheri.Zone, len(c.Zone.LoadFiles)) + for _, zonefile := range c.Zone.LoadFiles { logrus.WithFields(logrus.Fields{ "file": zonefile, }).Info("loading zone") - _, err := pancheri.LoadZone(zonefile) + zone, err := pancheri.LoadZone(zonefile) if err != nil { logrus.Errorf("failed to load zone %s: %s", zonefile, err) os.Exit(1) } + authoritativeZone := "." + zone.Root + "." + logrus.WithFields(logrus.Fields{ + "rsha": zone.ReducedHash, + "root": authoritativeZone, + }).Info("zone loaded") + zones[authoritativeZone] = zone } logrus.WithFields(logrus.Fields{ @@ -60,6 +68,9 @@ func main() { handler := pancheri.Handler{ C: c, R: r, + A: &pancheri.Authority{ + Zones: zones, + }, } server := &dns.Server{ Addr: c.Server.Host + ":" + c.Server.Port, diff --git a/handler.go b/handler.go index 545ced1..10e7da4 100644 --- a/handler.go +++ b/handler.go @@ -8,41 +8,46 @@ import ( type Handler struct { C *Config R *Resolver + A *Authority } func (h *Handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { // figure out how we should resolve this + msg := new(dns.Msg) + msg.SetReply(r) + msg.Authoritative = true - // is this in our list of authoritative domains? - // TODO + if len(r.Question) != 1 { + msg.Rcode = dns.RcodeFormatError + err := w.WriteMsg(msg) + if err != nil { + logrus.Errorf("error responding: %s", err) + return + } + return + } + + question := r.Question[0] // 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...) + answers, rcode, err := h.R.Resolve(question.Name, question.Qtype) + if err != nil { + logrus.Errorf("error resolving: %s", err) + return } + msg.Rcode = rcode + msg.Answer = append(msg.Answer, answers...) - err := w.WriteMsg(msg) + 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 } diff --git a/resolver.go b/resolver.go index a4fe510..76df16e 100644 --- a/resolver.go +++ b/resolver.go @@ -17,7 +17,7 @@ func NewResolver(upstream string) *Resolver { } } -func (r *Resolver) Resolve(domain string, qtype uint16) ([]dns.RR, error) { +func (r *Resolver) Resolve(domain string, qtype uint16) ([]dns.RR, int, error) { logrus.WithFields(logrus.Fields{ "domain": domain, "qtype": qtype, @@ -33,5 +33,5 @@ func (r *Resolver) Resolve(domain string, qtype uint16) ([]dns.RR, error) { return nil, err } - return in.Answer, nil + return in.Answer, in.Rcode, nil } diff --git a/zone_config.go b/zone_config.go index 2d9de78..0605d07 100644 --- a/zone_config.go +++ b/zone_config.go @@ -4,7 +4,6 @@ import ( "crypto/sha256" "errors" "fmt" - "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" "net" "os" @@ -156,7 +155,5 @@ func LoadZone(path string) (*Zone, error) { } } - logrus.Debugf("%+v", zone) - return &zone, nil }