diff options
| author | radhitya <alif@radhitya.org> | 2026-06-23 05:36:25 +0700 |
|---|---|---|
| committer | radhitya <alif@radhitya.org> | 2026-06-23 05:36:25 +0700 |
| commit | 2c61900dd5efd81a5351513a20fa65580c8a6616 (patch) | |
| tree | 61bdd1abb0d4fead3d04197404f731f831b1b548 /internal/server | |
| parent | 786e88a56f1445b31f194920d832dd037bd2a2d1 (diff) | |
make if error for unsupported query type
Diffstat (limited to 'internal/server')
| -rw-r--r-- | internal/server/handler.go | 32 | ||||
| -rw-r--r-- | internal/server/server_test.go | 23 |
2 files changed, 46 insertions, 9 deletions
diff --git a/internal/server/handler.go b/internal/server/handler.go index 4516468..46699d6 100644 --- a/internal/server/handler.go +++ b/internal/server/handler.go @@ -1,20 +1,36 @@ package server import ( + "codeberg.org/miekg/dns" + "codeberg.org/miekg/dns/rdata" "context" + "errors" "io" + "linum/internal/blocklist" + "linum/internal/cache" + "linum/internal/resolver" "log/slog" "net" "net/netip" + "runtime/debug" "time" - - "codeberg.org/miekg/dns" - "codeberg.org/miekg/dns/rdata" - "linum/internal/blocklist" - "linum/internal/cache" ) func (s *Server) handleQuery(ctx context.Context, w dns.ResponseWriter, req *dns.Msg) { + defer func() { + if r := recover(); r != nil { + slog.Error("panic in query handler", "recover", r, "stack", string(debug.Stack())) + m := new(dns.Msg) + m.Response = true + m.Rcode = dns.RcodeServerFailure + if req != nil { + m.ID = req.ID + m.Question = req.Question + } + io.Copy(w, m) + } + }() + clientIP := parseClientIP(w.RemoteAddr()) if !s.isAllowed(clientIP) { slog.Warn("query denied by ACL", "client", clientIP) @@ -92,13 +108,17 @@ func (s *Server) buildResponse(req *dns.Msg) (*dns.Msg, bool) { reply, err := s.resolver.Lookup(ctx, qname, qtype) if err != nil { + rcode := dns.RcodeServerFailure + if errors.Is(err, resolver.ErrUnsupportedType) { + rcode = dns.RcodeNotImplemented + } slog.Error("resolution failed", "err", err, "qname", qname, "qtype", dns.TypeToString[qtype], ) m := new(dns.Msg) - m.Rcode = dns.RcodeServerFailure + m.Rcode = uint16(rcode) m.Response = true m.ID = req.ID m.Question = req.Question diff --git a/internal/server/server_test.go b/internal/server/server_test.go index 2340acd..93e2a69 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -1,15 +1,32 @@ package server import ( + "codeberg.org/miekg/dns" + "codeberg.org/miekg/dns/rdata" "context" + "linum/internal/resolver" "log/slog" "testing" "time" - - "codeberg.org/miekg/dns" - "linum/internal/resolver" ) +func TestBuildResponseUnknownType(t *testing.T) { + s := testServer(t) + m := new(dns.Msg) + m.Question = []dns.RR{&dns.RFC3597{ + Hdr: dns.Header{Name: "example.com.", Class: dns.ClassINET}, + RFC3597: rdata.RFC3597{RRType: 0xaa58}, + }} + + resp, _ := s.buildResponse(m) + if resp == nil { + t.Fatal("buildResponse returned nil") + } + if resp.Rcode != dns.RcodeNotImplemented { + t.Errorf("expected NOTIMPL, got %d", resp.Rcode) + } +} + func testServer(t *testing.T) *Server { t.Helper() r := resolver.New( |
