-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler.go
91 lines (77 loc) · 2.16 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package doh
import (
"context"
"github.com/miekg/dns"
"github.com/shplack/dns/pkg/blacklist"
"github.com/shplack/dns/pkg/cache"
"github.com/qdm12/golibs/logging"
)
type handler struct {
// External objects
ctx context.Context
logger logging.Logger
// Internal objects
dial dialFunc
client *dns.Client
cache cache.Cache
blist blacklist.BlackLister
}
func newDNSHandler(ctx context.Context, logger logging.Logger,
settings ServerSettings) dns.Handler {
return &handler{
ctx: ctx,
logger: logger,
dial: newDoHDial(settings.Resolver),
client: &dns.Client{},
cache: cache.New(settings.Cache),
blist: blacklist.NewMap(settings.Blacklist),
}
}
func (h *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
if h.cache != nil {
if response := h.cache.Get(r); response != nil {
response.SetReply(r)
if err := w.WriteMsg(response); err != nil {
h.logger.Warn("cannot write DNS message back to client: " + err.Error())
}
return
}
}
if h.blist.FilterRequest(r) {
response := new(dns.Msg).SetRcode(r, dns.RcodeRefused)
if err := w.WriteMsg(response); err != nil {
h.logger.Warn("cannot write DNS message back to client: " + err.Error())
}
return
}
DoHConn, err := h.dial(h.ctx, "", "")
if err != nil {
h.logger.Warn("cannot dial: " + err.Error())
_ = w.WriteMsg(new(dns.Msg).SetRcode(r, dns.RcodeServerFailure))
return
}
conn := &dns.Conn{Conn: DoHConn}
response, _, err := h.client.ExchangeWithConn(r, conn)
if err := conn.Close(); err != nil {
h.logger.Warn("cannot close the DoT connection: " + err.Error())
}
if err != nil {
h.logger.Warn("cannot exchange over DoH connection: " + err.Error())
_ = w.WriteMsg(new(dns.Msg).SetRcode(r, dns.RcodeServerFailure))
return
}
if h.blist.FilterResponse(response) {
response := new(dns.Msg).SetRcode(r, dns.RcodeRefused)
if err := w.WriteMsg(response); err != nil {
h.logger.Warn("cannot write DNS message back to client: " + err.Error())
}
return
}
if h.cache != nil {
h.cache.Add(r, response)
}
response.SetReply(r)
if err := w.WriteMsg(response); err != nil {
h.logger.Warn("cannot write DNS message back to client: " + err.Error())
}
}