ServeDNS handles an incoming DNS query and writes the response.
(w dns.ResponseWriter, r *dns.Msg)
| 18 | |
| 19 | // ServeDNS handles an incoming DNS query and writes the response. |
| 20 | func (d dnsHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { |
| 21 | // Don't allow concurrent queries. |
| 22 | d.server.mu.Lock() |
| 23 | defer d.server.mu.Unlock() |
| 24 | |
| 25 | // Check if we're ready to serve queries. |
| 26 | if d.server.zoneRetriever == nil { |
| 27 | m := &dns.Msg{} |
| 28 | m.SetRcode(r, dns.RcodeServerFailure) |
| 29 | err := w.WriteMsg(m) |
| 30 | if err != nil { |
| 31 | logger.Error("Unable to write message", logger.Ctx{"err": err}) |
| 32 | } |
| 33 | |
| 34 | return |
| 35 | } |
| 36 | |
| 37 | // Only allow a single request. |
| 38 | if len(r.Question) != 1 { |
| 39 | m := &dns.Msg{} |
| 40 | m.SetRcode(r, dns.RcodeServerFailure) |
| 41 | err := w.WriteMsg(m) |
| 42 | if err != nil { |
| 43 | logger.Error("Unable to write message", logger.Ctx{"err": err}) |
| 44 | } |
| 45 | |
| 46 | return |
| 47 | } |
| 48 | |
| 49 | // Check that it's a supported request type. |
| 50 | if r.Question[0].Qtype != dns.TypeAXFR && r.Question[0].Qtype != dns.TypeIXFR && r.Question[0].Qtype != dns.TypeSOA { |
| 51 | m := &dns.Msg{} |
| 52 | m.SetRcode(r, dns.RcodeNotImplemented) |
| 53 | err := w.WriteMsg(m) |
| 54 | if err != nil { |
| 55 | logger.Error("Unable to write message", logger.Ctx{"err": err}) |
| 56 | } |
| 57 | |
| 58 | return |
| 59 | } |
| 60 | |
| 61 | // Extract the request information. |
| 62 | name := strings.TrimSuffix(r.Question[0].Name, ".") |
| 63 | ip, _, err := net.SplitHostPort(w.RemoteAddr().String()) |
| 64 | if err != nil { |
| 65 | m := &dns.Msg{} |
| 66 | m.SetRcode(r, dns.RcodeServerFailure) |
| 67 | err := w.WriteMsg(m) |
| 68 | if err != nil { |
| 69 | logger.Error("Unable to write message", logger.Ctx{"err": err}) |
| 70 | } |
| 71 | |
| 72 | return |
| 73 | } |
| 74 | |
| 75 | // Prepare the response. |
| 76 | m := &dns.Msg{} |
| 77 | m.SetReply(r) |