Sam
81da49093d
All checks were successful
continuous-integration/drone/push Build is passing
Instead of copying the opts struct every time it gets passed around, it should be created once and passed through reference. This should reduce memory utilization, unfortunately I cannot test it since this program runs so fast pprof won't report anything useful. I think I found all of them 🙂 Co-authored-by: Sam Therapy <sam@samtherapy.net> Reviewed-on: #132 Reviewed-by: grumbulon <grumbulon@grumbulon.xyz>
102 lines
2.1 KiB
Go
102 lines
2.1 KiB
Go
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package resolvers
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net"
|
|
|
|
"git.froth.zone/sam/awl/pkg/util"
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
// StandardResolver is for UDP/TCP resolvers.
|
|
type StandardResolver struct {
|
|
opts *util.Options
|
|
}
|
|
|
|
var _ Resolver = (*StandardResolver)(nil)
|
|
|
|
// LookUp performs a DNS query.
|
|
func (resolver *StandardResolver) LookUp(msg *dns.Msg) (util.Response, error) {
|
|
var (
|
|
resp util.Response
|
|
err error
|
|
)
|
|
|
|
dnsClient := new(dns.Client)
|
|
dnsClient.Dialer = &net.Dialer{
|
|
Timeout: resolver.opts.Request.Timeout,
|
|
}
|
|
|
|
if resolver.opts.TCP || resolver.opts.TLS {
|
|
dnsClient.Net = tcp
|
|
} else {
|
|
dnsClient.Net = udp
|
|
}
|
|
|
|
switch {
|
|
case resolver.opts.IPv4:
|
|
dnsClient.Net += "4"
|
|
case resolver.opts.IPv6:
|
|
dnsClient.Net += "6"
|
|
}
|
|
|
|
if resolver.opts.TLS {
|
|
dnsClient.Net += "-tls"
|
|
dnsClient.TLSConfig = &tls.Config{
|
|
//nolint:gosec // This is intentional if the user requests it
|
|
InsecureSkipVerify: resolver.opts.TLSNoVerify,
|
|
ServerName: resolver.opts.TLSHost,
|
|
}
|
|
}
|
|
|
|
resolver.opts.Logger.Info("Using", dnsClient.Net, "for making the request")
|
|
|
|
resp.DNS, resp.RTT, err = dnsClient.Exchange(msg, resolver.opts.Request.Server)
|
|
if err != nil {
|
|
return util.Response{}, fmt.Errorf("standard: DNS exchange: %w", err)
|
|
}
|
|
|
|
switch dns.RcodeToString[resp.DNS.MsgHdr.Rcode] {
|
|
case "BADCOOKIE":
|
|
if !resolver.opts.BadCookie {
|
|
fmt.Printf(";; BADCOOKIE, retrying.\n\n")
|
|
|
|
msg.Extra = resp.DNS.Extra
|
|
|
|
resp.DNS, resp.RTT, err = dnsClient.Exchange(msg, resolver.opts.Request.Server)
|
|
|
|
if err != nil {
|
|
return util.Response{}, fmt.Errorf("badcookie: DNS exchange: %w", err)
|
|
}
|
|
}
|
|
|
|
case "NOERR":
|
|
break
|
|
}
|
|
|
|
resolver.opts.Logger.Info("Request successful")
|
|
|
|
if resp.DNS.MsgHdr.Truncated && !resolver.opts.Truncate {
|
|
fmt.Printf(";; Truncated, retrying with TCP\n\n")
|
|
|
|
dnsClient.Net = tcp
|
|
|
|
switch {
|
|
case resolver.opts.IPv4:
|
|
dnsClient.Net += "4"
|
|
case resolver.opts.IPv6:
|
|
dnsClient.Net += "6"
|
|
}
|
|
|
|
resp.DNS, resp.RTT, err = dnsClient.Exchange(msg, resolver.opts.Request.Server)
|
|
}
|
|
|
|
if err != nil {
|
|
return util.Response{}, fmt.Errorf("standard: DNS exchange: %w", err)
|
|
}
|
|
|
|
return resp, nil
|
|
}
|