diff --git a/pkg/models/models.go b/pkg/models/models.go index 07c8611..cdcf6c1 100644 --- a/pkg/models/models.go +++ b/pkg/models/models.go @@ -39,6 +39,7 @@ type QueryFlags struct { Strategy string `koanf:"strategy" strategy:"-"` InsecureSkipVerify bool `koanf:"skip-hostname-verification" skip-hostname-verification:"-"` TLSHostname string `koanf:"tls-hostname" tls-hostname:"-"` + RetryCount int `koanf:"retry" retry:"-"` } // Nameserver represents the type of Nameserver diff --git a/pkg/resolvers/classic.go b/pkg/resolvers/classic.go index 63d90cd..3732aa7 100644 --- a/pkg/resolvers/classic.go +++ b/pkg/resolvers/classic.go @@ -63,14 +63,14 @@ func NewClassicResolver(server string, classicOpts ClassicResolverOpts, resolver func (r *ClassicResolver) Lookup(question dns.Question) (Response, error) { var ( rsp Response - messages = prepareMessages(question, r.resolverOptions.Ndots, r.resolverOptions.SearchList) + messages = prepareMessages(question, r.resolverOptions) ) for _, msg := range messages { r.resolverOptions.Logger.WithFields(logf.Fields{ "domain": msg.Question[0].Name, "ndots": r.resolverOptions.Ndots, "nameserver": r.server, - }).Debug("Attempting to resolve") + }).Debug("attempting to resolve") // Since the library doesn't include tcp.Dial time, // it's better to not rely on `rtt` provided here and calculate it ourselves. diff --git a/pkg/resolvers/dnscrypt.go b/pkg/resolvers/dnscrypt.go index eabbcc1..182132f 100644 --- a/pkg/resolvers/dnscrypt.go +++ b/pkg/resolvers/dnscrypt.go @@ -46,14 +46,14 @@ func NewDNSCryptResolver(server string, dnscryptOpts DNSCryptResolverOpts, resol func (r *DNSCryptResolver) Lookup(question dns.Question) (Response, error) { var ( rsp Response - messages = prepareMessages(question, r.resolverOptions.Ndots, r.resolverOptions.SearchList) + messages = prepareMessages(question, r.resolverOptions) ) for _, msg := range messages { r.resolverOptions.Logger.WithFields(logf.Fields{ "domain": msg.Question[0].Name, "ndots": r.resolverOptions.Ndots, "nameserver": r.server, - }).Debug("Attempting to resolve") + }).Debug("attempting to resolve") now := time.Now() in, err := r.client.Exchange(&msg, r.resolverInfo) if err != nil { diff --git a/pkg/resolvers/doh.go b/pkg/resolvers/doh.go index c781131..1db30ad 100644 --- a/pkg/resolvers/doh.go +++ b/pkg/resolvers/doh.go @@ -45,7 +45,7 @@ func NewDOHResolver(server string, resolverOpts Options) (Resolver, error) { func (r *DOHResolver) Lookup(question dns.Question) (Response, error) { var ( rsp Response - messages = prepareMessages(question, r.resolverOptions.Ndots, r.resolverOptions.SearchList) + messages = prepareMessages(question, r.resolverOptions) ) for _, msg := range messages { @@ -53,7 +53,7 @@ func (r *DOHResolver) Lookup(question dns.Question) (Response, error) { "domain": msg.Question[0].Name, "ndots": r.resolverOptions.Ndots, "nameserver": r.server, - }).Debug("Attempting to resolve") + }).Debug("attempting to resolve") // get the DNS Message in wire format. b, err := msg.Pack() if err != nil { diff --git a/pkg/resolvers/doq.go b/pkg/resolvers/doq.go index 870e117..fc260be 100644 --- a/pkg/resolvers/doq.go +++ b/pkg/resolvers/doq.go @@ -37,7 +37,7 @@ func NewDOQResolver(server string, resolverOpts Options) (Resolver, error) { func (r *DOQResolver) Lookup(question dns.Question) (Response, error) { var ( rsp Response - messages = prepareMessages(question, r.resolverOptions.Ndots, r.resolverOptions.SearchList) + messages = prepareMessages(question, r.resolverOptions) ) session, err := quic.DialAddr(r.server, r.tls, nil) @@ -51,7 +51,7 @@ func (r *DOQResolver) Lookup(question dns.Question) (Response, error) { "domain": msg.Question[0].Name, "ndots": r.resolverOptions.Ndots, "nameserver": r.server, - }).Debug("Attempting to resolve") + }).Debug("attempting to resolve") // ref: https://www.rfc-editor.org/rfc/rfc9250.html#name-dns-message-ids msg.Id = 0 diff --git a/pkg/resolvers/resolver.go b/pkg/resolvers/resolver.go index f6ae560..4f942a3 100644 --- a/pkg/resolvers/resolver.go +++ b/pkg/resolvers/resolver.go @@ -22,6 +22,12 @@ type Options struct { Strategy string InsecureSkipVerify bool TLSHostname string + + // DNS Protocol Flags. + Authoritative bool + AuthenticatedData bool + CheckingDisabled bool + RecursionDesired bool } // Resolver implements the configuration for a DNS diff --git a/pkg/resolvers/utils.go b/pkg/resolvers/utils.go index 4aded7d..8a20492 100644 --- a/pkg/resolvers/utils.go +++ b/pkg/resolvers/utils.go @@ -11,17 +11,22 @@ import ( // prepareMessages takes a DNS Question and returns the // corresponding DNS messages for the same. -func prepareMessages(q dns.Question, ndots int, searchList []string) []dns.Msg { +func prepareMessages(q dns.Question, opts Options) []dns.Msg { var ( - possibleQNames = constructPossibleQuestions(q.Name, ndots, searchList) + possibleQNames = constructPossibleQuestions(q.Name, opts.Ndots, opts.SearchList) messages = make([]dns.Msg, 0, len(possibleQNames)) ) for _, qName := range possibleQNames { - msg := dns.Msg{} - // generate a random id for the transaction. - msg.Id = dns.Id() - msg.RecursionDesired = true + msg := dns.Msg{ + MsgHdr: dns.MsgHdr{ + Id: dns.Id(), + Authoritative: opts.Authoritative, + AuthenticatedData: opts.AuthenticatedData, + CheckingDisabled: opts.CheckingDisabled, + RecursionDesired: opts.RecursionDesired, + }, + } // It's recommended to only send 1 question for 1 DNS message. msg.Question = []dns.Question{{ Name: qName,