blocky/resolver/resolver.go

148 lines
3.5 KiB
Go
Raw Normal View History

2020-01-12 18:23:35 +01:00
package resolver
import (
2020-02-23 22:32:24 +01:00
"fmt"
2020-01-12 18:23:35 +01:00
"net"
2020-02-23 22:32:24 +01:00
"strings"
"time"
2020-01-12 18:23:35 +01:00
2021-08-25 22:06:34 +02:00
"github.com/0xERR0R/blocky/log"
"github.com/0xERR0R/blocky/model"
2021-08-25 22:06:34 +02:00
"github.com/0xERR0R/blocky/util"
"github.com/miekg/dns"
2021-08-25 22:06:34 +02:00
2020-01-12 18:23:35 +01:00
"github.com/sirupsen/logrus"
)
func newRequest(question string, rType dns.Type, logger ...*logrus.Entry) *model.Request {
2021-01-16 22:24:05 +01:00
var loggerEntry *logrus.Entry
if len(logger) == 1 {
loggerEntry = logger[0]
} else {
loggerEntry = logrus.NewEntry(log.Log())
2021-01-16 22:24:05 +01:00
}
return &model.Request{
Req: util.NewMsgWithQuestion(question, rType),
2021-01-16 22:24:05 +01:00
Log: loggerEntry,
2021-09-09 22:57:05 +02:00
Protocol: model.RequestProtocolUDP,
2020-05-04 22:20:13 +02:00
}
}
func newRequestWithClient(question string, rType dns.Type, ip string, clientNames ...string) *model.Request {
return &model.Request{
2020-05-04 22:20:13 +02:00
ClientIP: net.ParseIP(ip),
ClientNames: clientNames,
Req: util.NewMsgWithQuestion(question, rType),
Log: logrus.NewEntry(log.Log()),
2020-05-04 22:20:13 +02:00
RequestTS: time.Time{},
2021-09-09 22:57:05 +02:00
Protocol: model.RequestProtocolUDP,
2020-05-04 22:20:13 +02:00
}
}
// newResponseMsg creates a new dns.Msg as response for a request
func newResponseMsg(request *model.Request) *dns.Msg {
response := new(dns.Msg)
response.SetReply(request.Req)
return response
}
// returnResponseModel wrapps a dns.Msg into a model.Response
func returnResponseModel(response *dns.Msg, rtype model.ResponseType, reason string) (*model.Response, error) {
return &model.Response{
Res: response,
RType: rtype,
Reason: reason,
}, nil
}
func newRequestWithClientID(question string, rType dns.Type, ip string, requestClientID string) *model.Request {
return &model.Request{
ClientIP: net.ParseIP(ip),
RequestClientID: requestClientID,
Req: util.NewMsgWithQuestion(question, rType),
Log: logrus.NewEntry(log.Log()),
RequestTS: time.Time{},
Protocol: model.RequestProtocolUDP,
}
}
// Resolver generic interface for all resolvers
2020-01-12 18:23:35 +01:00
type Resolver interface {
2021-02-26 21:39:41 +01:00
// Resolve performs resolution of a DNS request
Resolve(req *model.Request) (*model.Response, error)
2021-02-26 21:39:41 +01:00
// Configuration returns current resolver configuration
2020-01-12 18:23:35 +01:00
Configuration() []string
}
// ChainedResolver represents a resolver, which can delegate result to the next one
2020-01-12 18:23:35 +01:00
type ChainedResolver interface {
Resolver
2021-02-26 21:39:41 +01:00
2021-02-26 21:44:53 +01:00
// Next sets the next resolver
2020-01-12 18:23:35 +01:00
Next(n Resolver)
2021-02-26 21:39:41 +01:00
// GetNext returns the next resolver
2020-01-12 18:23:35 +01:00
GetNext() Resolver
}
// NextResolver is the base implementation of ChainedResolver
2020-01-12 18:23:35 +01:00
type NextResolver struct {
next Resolver
}
2021-02-26 21:44:53 +01:00
// Next sets the next resolver
2020-01-12 18:23:35 +01:00
func (r *NextResolver) Next(n Resolver) {
r.next = n
}
2021-02-26 21:44:53 +01:00
// GetNext returns the next resolver
2020-01-12 18:23:35 +01:00
func (r *NextResolver) GetNext() Resolver {
return r.next
}
// NamedResolver is a resolver with a special name
type NamedResolver interface {
// Name returns the full name of the resolver
Name() string
}
2020-01-12 18:23:35 +01:00
func logger(prefix string) *logrus.Entry {
return log.PrefixedLog(prefix)
2020-01-12 18:23:35 +01:00
}
func withPrefix(logger *logrus.Entry, prefix string) *logrus.Entry {
return logger.WithField("prefix", prefix)
}
// Chain creates a chain of resolvers
func Chain(resolvers ...Resolver) Resolver {
for i, res := range resolvers {
if i+1 < len(resolvers) {
if cr, ok := res.(ChainedResolver); ok {
cr.Next(resolvers[i+1])
}
}
}
return resolvers[0]
}
2020-02-23 22:32:24 +01:00
// Name returns a user-friendly name of a resolver
2020-02-23 22:32:24 +01:00
func Name(resolver Resolver) string {
if named, ok := resolver.(NamedResolver); ok {
return named.Name()
}
return defaultName(resolver)
}
// defaultName returns a short user-friendly name of a resolver
func defaultName(resolver Resolver) string {
2020-02-23 22:32:24 +01:00
return strings.Split(fmt.Sprintf("%T", resolver), ".")[1]
}