diff --git a/ex/fks/main.go b/ex/fks/main.go new file mode 100644 index 00000000..0f5319d3 --- /dev/null +++ b/ex/fks/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "dns" + "flag" + "log" + "os" +) + +var ( + z = flag.String("zone", "", "zonefile to read") + o = flag.String("origin", "", "origin of the zone") +) + +func main() { + flag.Parse() + if *z == "" { + log.Fatal("no zone") + } + if *o == "" { + log.Fatal("no origin") + } + Z := make(map[string]*dns.Zone) + if e := addZone(Z, *o, *z); e != nil { + log.Fatal("Huh %s\n", e.Error()) + } + dns.HandleFunc(*o, func(w dns.ResponseWriter, req *dns.Msg) { serve(w, req, Z[dns.Fqdn(*o)]) }) + go func() { + err := dns.ListenAndServe(":8053", "udp", nil) + if err != nil { + log.Fatal("Could not start") + } + }() + sig := make(chan os.Signal) +forever: + for { + select { + case <-sig: + log.Printf("Signal received, stopping\n") + break forever + } + } +} diff --git a/ex/fks/serve.go b/ex/fks/serve.go index 8ef72ebf..96e78ac5 100644 --- a/ex/fks/serve.go +++ b/ex/fks/serve.go @@ -2,8 +2,26 @@ package main import ( "dns" + "log" ) func serve(w dns.ResponseWriter, req *dns.Msg, z *dns.Zone) { - // nil + // See RFC 1035... + + log.Printf("incoming %s\n", req.Question[0].Name) + // dynamic updates + m := new(dns.Msg) + m.SetRcode(req, dns.RcodeNameError) + + // For now: + // look up name -> yes, continue, no -> nxdomain + node := z.Find(req.Question[0].Name) + if node == nil { + log.Printf("nothing found") + m := new(dns.Msg) + m.SetRcode(req, dns.RcodeNameError) + w.Write(m) + return + } + w.Write(m) } diff --git a/ex/fks/zones.go b/ex/fks/zones.go index c9815a42..7ae6eb4d 100644 --- a/ex/fks/zones.go +++ b/ex/fks/zones.go @@ -3,16 +3,9 @@ package main import ( "dns" "errors" - "flag" - "log" "os" ) -var ( - z = flag.String("zone", "", "zonefile to read") - o = flag.String("origin", "", "origin of the zone") -) - // Read a zone and add it. func addZone(zones map[string]*dns.Zone, origin, file string) error { origin = dns.Fqdn(origin) @@ -33,32 +26,3 @@ func addZone(zones map[string]*dns.Zone, origin, file string) error { zones[origin] = z1 return nil } - -// zone origin file -func main() { - flag.Parse() - if *z == "" { - log.Fatal("no zone") - } - if *o == "" { - log.Fatal("no origin") - } - Z := make(map[string]*dns.Zone) - addZone(Z, *o, *z) - dns.HandleFunc(*o, func(w dns.ResponseWriter, req *dns.Msg) { serve(w, req, Z[*o]) }) - go func() { - err := dns.ListenAndServe(":8053", "udp", nil) - if err != nil { - log.Fatal("Could not start") - } - }() - sig := make(chan os.Signal) -forever: - for { - select { - case <-sig: - log.Printf("Signal received, stopping\n") - break forever - } - } -} diff --git a/server.go b/server.go index cb65e371..3701725f 100644 --- a/server.go +++ b/server.go @@ -134,7 +134,8 @@ func (mux *ServeMux) HandleRemove(pattern string) { } // ServeDNS dispatches the request to the handler whose -// pattern most closely matches the request message. +// pattern most closely matches the request message. For DS queries +// a parent zone is sought. // If no handler is found a standard SERVFAIL message is returned func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) { h := mux.match(request.Question[0].Name) @@ -354,6 +355,9 @@ func (w *response) Write(m *Msg) (err error) { data []byte ok bool ) + if m == nil { + return &Error{Err: "nil message"} + } if m.IsTsig() { data, w.tsigRequestMAC, err = TsigGenerate(m, w.conn.tsigSecret[m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly) if err != nil { diff --git a/zone.go b/zone.go index 91230e03..d3d87d92 100644 --- a/zone.go +++ b/zone.go @@ -30,7 +30,7 @@ type ZoneData struct { func toRadixName(d string) string { s := "" for _, l := range SplitLabels(d) { - s = strings.ToLower(l) + s + s = strings.ToLower(l) + "." + s } return s } @@ -96,3 +96,18 @@ func (z *Zone) Insert(r RR) error { func (z *Zone) Remove(r RR) error { return nil } + +// Find search the zone data and returns a node or nil when +// nothing is found. +func (z *Zone) Find(s string) *ZoneData { + println("looking for", toRadixName(s)) + if z.Radix == nil { + println("huh nil") + return nil + } + zd := z.Radix.Find(toRadixName(s)) + if zd == nil { + return nil + } + return zd.Value.(*ZoneData) +}