summaryrefslogtreecommitdiff
path: root/internal/server/handler.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/server/handler.go')
-rw-r--r--internal/server/handler.go65
1 files changed, 65 insertions, 0 deletions
diff --git a/internal/server/handler.go b/internal/server/handler.go
new file mode 100644
index 0000000..2e2f08b
--- /dev/null
+++ b/internal/server/handler.go
@@ -0,0 +1,65 @@
+package server
+
+import (
+ "github.com/miekg/dns"
+ "log/slog"
+)
+
+func handleQuery(w dns.ResponseWriter, req *dns.Msg) {
+ if len(req.Question) == 0 {
+ m := new(dns.Msg)
+ m.SetRcode(req, dns.RcodeFormatError)
+ _ = w.WriteMsg(m)
+ return
+ }
+
+ resp := buildResponse(req)
+
+ if err := w.WriteMsg(resp); err != nil {
+ slog.Error("write response failed",
+ "err", err,
+ "qname", req.Question[0].Name,
+ "qtype", dns.TypeToString[req.Question[0].Qtype],
+ )
+ return
+ }
+ slog.Info("query served",
+ "qname", req.Question[0].Name,
+ "qtype", dns.TypeToString[req.Question[0].Qtype],
+ "rcode", dns.RcodeToString[resp.Rcode],
+ "client", w.RemoteAddr().String(),
+ )
+}
+
+func buildResponse(req *dns.Msg) *dns.Msg {
+ if len(req.Question) == 0 {
+ m := new(dns.Msg)
+ m.SetRcode(req, dns.RcodeFormatError)
+ return m
+ }
+ q := req.Question[0]
+ resp := new(dns.Msg)
+ resp.SetReply(req)
+ resp.Authoritative = false
+
+ if opt := req.IsEdns0(); opt != nil {
+ resp.SetEdns0(4096, false)
+ }
+
+ if q.Name == "example.com." && q.Qtype == dns.TypeA {
+ resp.Answer = []dns.RR{
+ &dns.A{
+ Hdr: dns.RR_Header{
+ Name: q.Name,
+ Rrtype: dns.TypeA,
+ Class: dns.ClassINET,
+ Ttl: 60,
+ },
+ A: []byte{127, 0, 0, 1},
+ },
+ }
+ } else {
+ resp.Rcode = dns.RcodeNameError
+ }
+ return resp
+}