1package resolver 2 3import ( 4 "fmt" 5 "net" 6 "strings" 7 "time" 8 9 "github.com/0xERR0R/blocky/log" 10 "github.com/0xERR0R/blocky/model" 11 "github.com/0xERR0R/blocky/util" 12 13 "github.com/sirupsen/logrus" 14) 15 16func newRequest(question string, rType uint16, logger ...*logrus.Entry) *model.Request { 17 var loggerEntry *logrus.Entry 18 if len(logger) == 1 { 19 loggerEntry = logger[0] 20 } else { 21 loggerEntry = logrus.NewEntry(log.Log()) 22 } 23 24 return &model.Request{ 25 Req: util.NewMsgWithQuestion(question, rType), 26 Log: loggerEntry, 27 Protocol: model.RequestProtocolUDP, 28 } 29} 30 31func newRequestWithClient(question string, rType uint16, ip string, clientNames ...string) *model.Request { 32 return &model.Request{ 33 ClientIP: net.ParseIP(ip), 34 ClientNames: clientNames, 35 Req: util.NewMsgWithQuestion(question, rType), 36 Log: logrus.NewEntry(log.Log()), 37 RequestTS: time.Time{}, 38 Protocol: model.RequestProtocolUDP, 39 } 40} 41 42func newRequestWithClientID(question string, rType uint16, ip string, requestClientID string) *model.Request { 43 return &model.Request{ 44 ClientIP: net.ParseIP(ip), 45 RequestClientID: requestClientID, 46 Req: util.NewMsgWithQuestion(question, rType), 47 Log: logrus.NewEntry(log.Log()), 48 RequestTS: time.Time{}, 49 Protocol: model.RequestProtocolUDP, 50 } 51} 52 53// Resolver generic interface for all resolvers 54type Resolver interface { 55 56 // Resolve performs resolution of a DNS request 57 Resolve(req *model.Request) (*model.Response, error) 58 59 // Configuration prints current resolver configuration 60 Configuration() []string 61} 62 63// ChainedResolver represents a resolver, which can delegate result to the next one 64type ChainedResolver interface { 65 Resolver 66 67 // Next sets the next resolver 68 Next(n Resolver) 69 70 // GetNext returns the next resolver 71 GetNext() Resolver 72} 73 74// NextResolver is the base implementation of ChainedResolver 75type NextResolver struct { 76 next Resolver 77} 78 79// Next sets the next resolver 80func (r *NextResolver) Next(n Resolver) { 81 r.next = n 82} 83 84// GetNext returns the next resolver 85func (r *NextResolver) GetNext() Resolver { 86 return r.next 87} 88 89func logger(prefix string) *logrus.Entry { 90 return log.PrefixedLog(prefix) 91} 92 93func withPrefix(logger *logrus.Entry, prefix string) *logrus.Entry { 94 return logger.WithField("prefix", prefix) 95} 96 97// Chain creates a chain of resolvers 98func Chain(resolvers ...Resolver) Resolver { 99 for i, res := range resolvers { 100 if i+1 < len(resolvers) { 101 if cr, ok := res.(ChainedResolver); ok { 102 cr.Next(resolvers[i+1]) 103 } 104 } 105 } 106 107 return resolvers[0] 108} 109 110// Name returns a user-friendly name of a resolver 111func Name(resolver Resolver) string { 112 return strings.Split(fmt.Sprintf("%T", resolver), ".")[1] 113} 114