Skip to content

Commit

Permalink
chore(all): cache and filter are middlewares
Browse files Browse the repository at this point in the history
  • Loading branch information
qdm12 committed Aug 10, 2023
1 parent e694c83 commit 23681aa
Show file tree
Hide file tree
Showing 20 changed files with 167 additions and 261 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,3 +312,5 @@ docker build -t qmcgaw/dns .
```
See [Contributing](.github/CONTRIBUTING.md) for more information on how to contribute to this repository.
move stateful to internal
8 changes: 6 additions & 2 deletions examples/doh-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"syscall"

"github.com/qdm12/dns/v2/pkg/cache/lru"
cachemiddleware "github.com/qdm12/dns/v2/pkg/cache/middleware"
"github.com/qdm12/dns/v2/pkg/doh"
)

Expand All @@ -16,9 +17,12 @@ func main() {
defer stop()

logger := new(Logger)

cacheMiddleware := cachemiddleware.New(lru.New(lru.Settings{}))

server, err := doh.NewServer(doh.ServerSettings{
Cache: lru.New(lru.Settings{}),
Logger: logger,
Middlewares: []doh.Middleware{cacheMiddleware},
Logger: logger,
})
if err != nil {
log.Fatal(err)
Expand Down
8 changes: 6 additions & 2 deletions examples/dot-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"syscall"

"github.com/qdm12/dns/v2/pkg/cache/lru"
cachemiddleware "github.com/qdm12/dns/v2/pkg/cache/middleware"
"github.com/qdm12/dns/v2/pkg/dot"
)

Expand All @@ -16,9 +17,12 @@ func main() {
defer stop()

logger := new(Logger)

cacheMiddleware := cachemiddleware.New(lru.New(lru.Settings{}))

server, err := dot.NewServer(dot.ServerSettings{
Cache: lru.New(lru.Settings{}),
Logger: logger,
Middlewares: []dot.Middleware{cacheMiddleware},
Logger: logger,
})
if err != nil {
log.Fatal(err)
Expand Down
32 changes: 1 addition & 31 deletions internal/server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,26 @@ var _ dns.Handler = (*Handler)(nil)
type Handler struct {
ctx context.Context //nolint:containedctx
exchange Exchange
filter Filter
cache Cache
logger Logger
}

func New(ctx context.Context, exchange Exchange,
filter Filter, cache Cache, logger Logger) *Handler {
logger Logger) *Handler {
return &Handler{
ctx: ctx,
exchange: exchange,
filter: filter,
cache: cache,
logger: logger,
}
}

func (h *Handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
if h.filter.FilterRequest(r) {
response := new(dns.Msg).SetRcode(r, dns.RcodeRefused)
_ = w.WriteMsg(response)
return
}

if response := h.cache.Get(r); response != nil {
if h.filter.FilterResponse(response) {
h.cache.Remove(r)
response := new(dns.Msg).SetRcode(r, dns.RcodeRefused)
_ = w.WriteMsg(response)
return
}
response.SetReply(r)
_ = w.WriteMsg(response)
return
}

response, err := h.exchange(h.ctx, r)
if err != nil {
h.logger.Warn(err.Error())
_ = w.WriteMsg(new(dns.Msg).SetRcode(r, dns.RcodeServerFailure))
return
}

if h.filter.FilterResponse(response) {
response := new(dns.Msg).SetRcode(r, dns.RcodeRefused)
_ = w.WriteMsg(response)
return
}

h.cache.Add(r, response)

response.SetReply(r)
_ = w.WriteMsg(response)
}
171 changes: 10 additions & 161 deletions internal/server/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,13 @@ func Test_New(t *testing.T) {
t.Parallel()

ctx := context.Background()
filter := NewMockFilter(nil)
cache := NewMockCache(nil)
logger := NewMockLogger(nil)

handler := New(ctx, nil, filter, cache, logger)
handler := New(ctx, nil, logger)

expectedHandler := &Handler{
ctx: ctx,
exchange: nil, // cannot compare functions
filter: filter,
cache: cache,
logger: logger,
}
assert.Equal(t, expectedHandler, handler)
Expand All @@ -34,119 +30,28 @@ func Test_Handler_ServeDNS(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
makeHandler func(ctrl *gomock.Controller) *Handler
makeHandler func(t *testing.T, ctrl *gomock.Controller) *Handler
request *dns.Msg
response *dns.Msg
}{
"filtered_request": {
makeHandler: func(ctrl *gomock.Controller) *Handler {
filter := NewMockFilter(ctrl)
filter.EXPECT().FilterRequest(&dns.Msg{
Question: []dns.Question{{Name: "test"}}},
).Return(true)
return &Handler{
filter: filter,
}
},
request: &dns.Msg{
Question: []dns.Question{{Name: "test"}},
},
response: &dns.Msg{
MsgHdr: dns.MsgHdr{
Response: true,
Rcode: dns.RcodeRefused,
},
Question: []dns.Question{{Name: "test"}},
},
},
"filtered_cached_response": {
makeHandler: func(ctrl *gomock.Controller) *Handler {
expectedRequest := &dns.Msg{
Question: []dns.Question{{Name: "test"}},
}

filter := NewMockFilter(ctrl)
filter.EXPECT().FilterRequest(expectedRequest).Return(false)

cache := NewMockCache(ctrl)
cachedResponse := &dns.Msg{Answer: []dns.RR{&dns.A{}}}
cache.EXPECT().Get(expectedRequest).Return(cachedResponse)

filter.EXPECT().FilterResponse(cachedResponse).Return(true)

cache.EXPECT().Remove(expectedRequest)

return &Handler{
filter: filter,
cache: cache,
}
},
request: &dns.Msg{
Question: []dns.Question{{Name: "test"}},
},
response: &dns.Msg{
MsgHdr: dns.MsgHdr{
Response: true,
Rcode: dns.RcodeRefused,
},
Question: []dns.Question{{Name: "test"}},
},
},
"cached_response": {
makeHandler: func(ctrl *gomock.Controller) *Handler {
expectedRequest := &dns.Msg{
Question: []dns.Question{{Name: "test"}},
}

filter := NewMockFilter(ctrl)
filter.EXPECT().FilterRequest(expectedRequest).Return(false)

cache := NewMockCache(ctrl)
cachedResponse := &dns.Msg{Answer: []dns.RR{&dns.A{}}}
cache.EXPECT().Get(expectedRequest).Return(cachedResponse)

filter.EXPECT().FilterResponse(cachedResponse).Return(false)

return &Handler{
filter: filter,
cache: cache,
}
},
request: &dns.Msg{
Question: []dns.Question{{Name: "test"}},
},
response: &dns.Msg{
MsgHdr: dns.MsgHdr{
Response: true,
},
Question: []dns.Question{{Name: "test"}},
Answer: []dns.RR{&dns.A{}},
},
},
"exchange_error": {
makeHandler: func(ctrl *gomock.Controller) *Handler {
makeHandler: func(t *testing.T, ctrl *gomock.Controller) *Handler {
t.Helper()
expectedRequest := &dns.Msg{
Question: []dns.Question{{Name: "test"}},
}

filter := NewMockFilter(ctrl)
filter.EXPECT().FilterRequest(expectedRequest).Return(false)

cache := NewMockCache(ctrl)
cache.EXPECT().Get(expectedRequest).Return(nil)

exchange := func(ctx context.Context, request *dns.Msg) (
response *dns.Msg, err error,
) {
assert.Equal(t, expectedRequest, request)
return nil, errors.New("test error")
}

logger := NewMockLogger(ctrl)
logger.EXPECT().Warn("test error")

return &Handler{
filter: filter,
cache: cache,
exchange: exchange,
logger: logger,
}
Expand All @@ -162,76 +67,20 @@ func Test_Handler_ServeDNS(t *testing.T) {
Question: []dns.Question{{Name: "test"}},
},
},
"filtered_exchanged_response": {
makeHandler: func(ctrl *gomock.Controller) *Handler {
expectedRequest := &dns.Msg{
Question: []dns.Question{{Name: "test"}},
}

filter := NewMockFilter(ctrl)
filter.EXPECT().FilterRequest(expectedRequest).Return(false)

cache := NewMockCache(ctrl)
cache.EXPECT().Get(expectedRequest).Return(nil)

expectedResponse := &dns.Msg{Answer: []dns.RR{&dns.A{}}}

exchange := func(ctx context.Context, request *dns.Msg) (
response *dns.Msg, err error,
) {
return expectedResponse, nil
}

filter.EXPECT().
FilterResponse(expectedResponse).
Return(true)

return &Handler{
filter: filter,
cache: cache,
exchange: exchange,
}
},
request: &dns.Msg{
Question: []dns.Question{{Name: "test"}},
},
response: &dns.Msg{
MsgHdr: dns.MsgHdr{
Response: true,
Rcode: dns.RcodeRefused,
},
Question: []dns.Question{{Name: "test"}},
},
},
"exchanged_response": {
makeHandler: func(ctrl *gomock.Controller) *Handler {
makeHandler: func(t *testing.T, _ *gomock.Controller) *Handler {
t.Helper()
expectedRequest := &dns.Msg{
Question: []dns.Question{{Name: "test"}},
}

filter := NewMockFilter(ctrl)
filter.EXPECT().FilterRequest(expectedRequest).Return(false)

cache := NewMockCache(ctrl)
cache.EXPECT().Get(expectedRequest).Return(nil)

expectedResponse := &dns.Msg{Answer: []dns.RR{&dns.A{}}}

exchange := func(ctx context.Context, request *dns.Msg) (
response *dns.Msg, err error,
) {
return expectedResponse, nil
assert.Equal(t, expectedRequest, request)
return &dns.Msg{Answer: []dns.RR{&dns.A{}}}, nil
}

filter.EXPECT().
FilterResponse(expectedResponse).
Return(false)

cache.EXPECT().Add(expectedRequest, expectedResponse)

return &Handler{
filter: filter,
cache: cache,
exchange: exchange,
}
},
Expand All @@ -254,7 +103,7 @@ func Test_Handler_ServeDNS(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)

handler := testCase.makeHandler(ctrl)
handler := testCase.makeHandler(t, ctrl)
writer := &testWriter{}

handler.ServeDNS(writer, testCase.request)
Expand Down
17 changes: 0 additions & 17 deletions internal/server/interfaces.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
package server

import (
"github.com/miekg/dns"
"github.com/qdm12/dns/v2/pkg/filter/update"
)

type Filter interface {
FilterRequest(request *dns.Msg) (blocked bool)
FilterResponse(response *dns.Msg) (blocked bool)
Update(settings update.Settings)
}

type Cache interface {
Add(request, response *dns.Msg)
Get(request *dns.Msg) (response *dns.Msg)
Remove(request *dns.Msg)
}

type Logger interface {
Debug(s string)
Info(s string)
Expand Down
Loading

0 comments on commit 23681aa

Please sign in to comment.