handle a DNS query payload here is the application-level UDP payload
(ctx context.Context, w io.Writer, payload []byte)
| 11 | |
| 12 | // handle a DNS query payload here is the application-level UDP payload |
| 13 | func handleDNS(ctx context.Context, w io.Writer, payload []byte) { |
| 14 | var req dns.Msg |
| 15 | err := req.Unpack(payload) |
| 16 | if err != nil { |
| 17 | errorf("error unpacking dns packet: %v, ignoring", err) |
| 18 | return |
| 19 | } |
| 20 | |
| 21 | if req.Opcode != dns.OpcodeQuery { |
| 22 | errorf("ignoring a dns query with non-query opcode (%v)", req.Opcode) |
| 23 | return |
| 24 | } |
| 25 | |
| 26 | // resolve the query |
| 27 | rrs, err := handleDNSQuery(ctx, &req) |
| 28 | if err != nil { |
| 29 | verbosef("DNS query returned: %v, sending a response with empty answer", err) |
| 30 | // do not abort here, continue on and send a reply with no answer |
| 31 | } |
| 32 | |
| 33 | resp := new(dns.Msg) |
| 34 | resp.SetReply(&req) |
| 35 | resp.Answer = rrs |
| 36 | |
| 37 | // serialize the response |
| 38 | buf, err := resp.Pack() |
| 39 | if err != nil { |
| 40 | errorf("error serializing dns response: %v, abandoning...", err) |
| 41 | return |
| 42 | } |
| 43 | |
| 44 | // always send the entire buffer in a single Write() since UDP writes one packet per call to Write() |
| 45 | verbosef("responding to DNS request with %d bytes...", len(buf)) |
| 46 | _, err = w.Write(buf) |
| 47 | if err != nil { |
| 48 | errorf("error writing dns response: %v, abandoning...", err) |
| 49 | return |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | func dnsTypeCode(t uint16) string { |
| 54 | switch t { |
no test coverage detected