Factor the making of handlers out

NB I removed free variables from the LookupFunc implementations, to
avoid confusion between `s` the receiver and the closed-over `s`.

Also corrected a mistake in the write error log message.
This commit is contained in:
Michael Bridgen committed 2015-01-09 12:29:28 +00:00
1 parent f24edf755f
commit 15ebc2c9a7
1 file changed
+42 -38
+42 -38
View File
@@ -50,46 +50,23 @@ func (s *MDNSServer) Start(ifi *net.Interface) error {
return err
}
handler := func(qtype uint16, lookup func(*dns.Msg, *dns.Question) *dns.Msg) dns.HandlerFunc {
return func(w dns.ResponseWriter, r *dns.Msg) {
// Handle only questions, ignore answers. We might also
// ignore questions that arise locally (i.e., that come
// from an IP we think is local), but in the interest of
// avoiding complication, and easier testing, this is
// elided on the assumption that the client wouldn't ask
// if it already knew the answer, and if it does ask,
// it'll be happy to get an answer.
if len(r.Answer) == 0 && len(r.Question) > 0 {
q := &r.Question[0]
if q.Qtype == qtype {
if m := lookup(r, q); m != nil {
Debug.Printf("Found local answer to mDNS query %s", q.Name)
if err = s.sendResponse(m); err != nil {
Warning.Printf("Error writing to %s", w)
}
} else {
Debug.Printf("No local answer for mDNS query %s", q.Name)
}
}
handleLocal := s.makeHandler(dns.TypeA,
func(zone Lookup, r *dns.Msg, q *dns.Question) *dns.Msg {
if ip, err := zone.LookupLocal(q.Name); err == nil {
return makeAddressReply(r, q, []net.IP{ip})
} else {
return nil
}
}
}
})
handleLocal := handler(dns.TypeA, func(r *dns.Msg, q *dns.Question) *dns.Msg {
if ip, err := s.zone.LookupLocal(q.Name); err == nil {
return makeAddressReply(r, q, []net.IP{ip})
} else {
return nil
}
})
handleReverse := handler(dns.TypePTR, func(r *dns.Msg, q *dns.Question) *dns.Msg {
if name, err := s.zone.ReverseLookupLocal(q.Name); err == nil {
return makePTRReply(r, q, []string{name})
} else {
return nil
}
})
handleReverse := s.makeHandler(dns.TypePTR,
func(zone Lookup, r *dns.Msg, q *dns.Question) *dns.Msg {
if name, err := zone.ReverseLookupLocal(q.Name); err == nil {
return makePTRReply(r, q, []string{name})
} else {
return nil
}
})
mux := dns.NewServeMux()
mux.HandleFunc(LOCAL_DOMAIN, handleLocal)
@@ -99,6 +76,33 @@ func (s *MDNSServer) Start(ifi *net.Interface) error {
return err
}
type LookupFunc func(Lookup, *dns.Msg, *dns.Question) *dns.Msg
func (s *MDNSServer) makeHandler(qtype uint16, lookup LookupFunc) dns.HandlerFunc {
return func(_ dns.ResponseWriter, r *dns.Msg) {
// Handle only questions, ignore answers. We might also ignore
// questions that arise locally (i.e., that come from an IP we
// think is local), but in the interest of avoiding
// complication, and easier testing, this is elided on the
// assumption that the client wouldn't ask if it already knew
// the answer, and if it does ask, it'll be happy to get an
// answer.
if len(r.Answer) == 0 && len(r.Question) > 0 {
q := &r.Question[0]
if q.Qtype == qtype {
if m := lookup(s.zone, r, q); m != nil {
Debug.Printf("Found local answer to mDNS query %s", q.Name)
if err := s.sendResponse(m); err != nil {
Warning.Printf("Error writing to %s", s.sendconn)
}
} else {
Debug.Printf("No local answer for mDNS query %s", q.Name)
}
}
}
}
}
func (s *MDNSServer) sendResponse(m *dns.Msg) error {
buf, err := m.Pack()
if err != nil {