diff --git a/nameserver/mdns_server.go b/nameserver/mdns_server.go index 2cca64de..cfab5721 100644 --- a/nameserver/mdns_server.go +++ b/nameserver/mdns_server.go @@ -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 {