2020-12-11 12:18:54 +01:00
|
|
|
package resolvers
|
|
|
|
|
2020-12-12 11:57:13 +01:00
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/miekg/dns"
|
2021-02-26 15:36:46 +01:00
|
|
|
"github.com/mr-karan/doggo/pkg/models"
|
2022-07-01 03:59:14 +02:00
|
|
|
"github.com/mr-karan/logf"
|
2020-12-12 11:57:13 +01:00
|
|
|
)
|
2020-12-11 12:18:54 +01:00
|
|
|
|
2020-12-24 17:25:20 +01:00
|
|
|
// Options represent a set of common options
|
|
|
|
// to configure a Resolver.
|
|
|
|
type Options struct {
|
2022-07-01 03:59:14 +02:00
|
|
|
Logger *logf.Logger
|
2022-05-18 06:26:07 +02:00
|
|
|
|
|
|
|
Nameservers []models.Nameserver
|
|
|
|
UseIPv4 bool
|
|
|
|
UseIPv6 bool
|
|
|
|
SearchList []string
|
|
|
|
Ndots int
|
|
|
|
Timeout time.Duration
|
|
|
|
Strategy string
|
|
|
|
InsecureSkipVerify bool
|
|
|
|
TLSHostname string
|
2020-12-24 17:25:20 +01:00
|
|
|
}
|
|
|
|
|
2020-12-12 07:16:13 +01:00
|
|
|
// Resolver implements the configuration for a DNS
|
2020-12-15 18:39:10 +01:00
|
|
|
// Client. Different types of providers can load
|
|
|
|
// a DNS Resolver satisfying this interface.
|
2020-12-11 12:18:54 +01:00
|
|
|
type Resolver interface {
|
2020-12-24 17:25:20 +01:00
|
|
|
Lookup(dns.Question) (Response, error)
|
2020-12-12 11:57:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Response represents a custom output format
|
2020-12-15 18:39:10 +01:00
|
|
|
// for DNS queries. It wraps metadata about the DNS query
|
2020-12-12 11:57:13 +01:00
|
|
|
// and the DNS Answer as well.
|
|
|
|
type Response struct {
|
2020-12-24 17:25:20 +01:00
|
|
|
Answers []Answer `json:"answers"`
|
|
|
|
Authorities []Authority `json:"authorities"`
|
|
|
|
Questions []Question `json:"questions"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Question struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Class string `json:"class"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Answer struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Class string `json:"class"`
|
|
|
|
TTL string `json:"ttl"`
|
|
|
|
Address string `json:"address"`
|
|
|
|
Status string `json:"status"`
|
|
|
|
RTT string `json:"rtt"`
|
|
|
|
Nameserver string `json:"nameserver"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Authority struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Class string `json:"class"`
|
|
|
|
TTL string `json:"ttl"`
|
|
|
|
MName string `json:"mname"`
|
|
|
|
Status string `json:"status"`
|
|
|
|
RTT string `json:"rtt"`
|
|
|
|
Nameserver string `json:"nameserver"`
|
2020-12-11 12:18:54 +01:00
|
|
|
}
|
2021-02-26 15:36:46 +01:00
|
|
|
|
|
|
|
// LoadResolvers loads differently configured
|
|
|
|
// resolvers based on a list of nameserver.
|
|
|
|
func LoadResolvers(opts Options) ([]Resolver, error) {
|
2022-05-18 06:26:07 +02:00
|
|
|
// For each nameserver, initialise the correct resolver.
|
2021-02-26 15:36:46 +01:00
|
|
|
rslvrs := make([]Resolver, 0, len(opts.Nameservers))
|
2022-05-18 06:26:07 +02:00
|
|
|
|
2021-02-26 15:36:46 +01:00
|
|
|
for _, ns := range opts.Nameservers {
|
|
|
|
if ns.Type == models.DOHResolver {
|
|
|
|
opts.Logger.Debug("initiating DOH resolver")
|
2022-05-18 06:26:07 +02:00
|
|
|
rslvr, err := NewDOHResolver(ns.Address, opts)
|
2021-02-26 15:36:46 +01:00
|
|
|
if err != nil {
|
|
|
|
return rslvrs, err
|
|
|
|
}
|
|
|
|
rslvrs = append(rslvrs, rslvr)
|
|
|
|
}
|
|
|
|
if ns.Type == models.DOTResolver {
|
|
|
|
opts.Logger.Debug("initiating DOT resolver")
|
|
|
|
rslvr, err := NewClassicResolver(ns.Address,
|
|
|
|
ClassicResolverOpts{
|
2022-05-18 06:26:07 +02:00
|
|
|
UseTLS: true,
|
|
|
|
UseTCP: true,
|
|
|
|
}, opts)
|
2021-02-26 15:36:46 +01:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return rslvrs, err
|
|
|
|
}
|
|
|
|
rslvrs = append(rslvrs, rslvr)
|
|
|
|
}
|
|
|
|
if ns.Type == models.TCPResolver {
|
|
|
|
opts.Logger.Debug("initiating TCP resolver")
|
|
|
|
rslvr, err := NewClassicResolver(ns.Address,
|
|
|
|
ClassicResolverOpts{
|
2022-05-18 06:26:07 +02:00
|
|
|
UseTLS: false,
|
|
|
|
UseTCP: true,
|
|
|
|
}, opts)
|
2021-02-26 15:36:46 +01:00
|
|
|
if err != nil {
|
|
|
|
return rslvrs, err
|
|
|
|
}
|
|
|
|
rslvrs = append(rslvrs, rslvr)
|
|
|
|
}
|
|
|
|
if ns.Type == models.UDPResolver {
|
|
|
|
opts.Logger.Debug("initiating UDP resolver")
|
|
|
|
rslvr, err := NewClassicResolver(ns.Address,
|
|
|
|
ClassicResolverOpts{
|
2022-05-18 06:26:07 +02:00
|
|
|
UseTLS: false,
|
|
|
|
UseTCP: false,
|
|
|
|
}, opts)
|
2021-02-26 15:36:46 +01:00
|
|
|
if err != nil {
|
|
|
|
return rslvrs, err
|
|
|
|
}
|
|
|
|
rslvrs = append(rslvrs, rslvr)
|
|
|
|
}
|
2021-04-24 17:27:43 +02:00
|
|
|
if ns.Type == models.DNSCryptResolver {
|
|
|
|
opts.Logger.Debug("initiating DNSCrypt resolver")
|
|
|
|
rslvr, err := NewDNSCryptResolver(ns.Address,
|
|
|
|
DNSCryptResolverOpts{
|
|
|
|
UseTCP: false,
|
2022-05-18 06:26:07 +02:00
|
|
|
}, opts)
|
2021-04-24 17:27:43 +02:00
|
|
|
if err != nil {
|
|
|
|
return rslvrs, err
|
|
|
|
}
|
|
|
|
rslvrs = append(rslvrs, rslvr)
|
|
|
|
}
|
2021-12-11 16:45:24 +01:00
|
|
|
if ns.Type == models.DOQResolver {
|
|
|
|
opts.Logger.Debug("initiating DOQ resolver")
|
2022-05-18 06:26:07 +02:00
|
|
|
rslvr, err := NewDOQResolver(ns.Address, opts)
|
2021-12-11 16:45:24 +01:00
|
|
|
if err != nil {
|
|
|
|
return rslvrs, err
|
|
|
|
}
|
|
|
|
rslvrs = append(rslvrs, rslvr)
|
|
|
|
}
|
2021-02-26 15:36:46 +01:00
|
|
|
}
|
|
|
|
return rslvrs, nil
|
|
|
|
}
|