Files
routedns/dnsclient.go
Frank Olbricht c0e135b786 Allow 4k responses (#95)
* Allow 4k responses

* Move UDP size config into the client
2020-10-11 08:12:18 -06:00

73 lines
1.7 KiB
Go

package rdns
import (
"crypto/tls"
"net"
"github.com/miekg/dns"
"github.com/sirupsen/logrus"
)
// DNSClient represents a simple DNS resolver for UDP or TCP.
type DNSClient struct {
id string
endpoint string
net string
pipeline *Pipeline
// Pipeline also provides operation metrics.
}
type DNSClientOptions struct {
// Local IP to use for outbound connections. If nil, a local address is chosen.
LocalAddr net.IP
}
var _ Resolver = &DNSClient{}
// NewDNSClient returns a new instance of DNSClient which is a plain DNS resolver
// that supports pipelining over a single connection.
func NewDNSClient(id, endpoint, network string, opt DNSClientOptions) (*DNSClient, error) {
if err := validEndpoint(endpoint); err != nil {
return nil, err
}
// Use a custom dialer if a local address was provided
var dialer *net.Dialer
if opt.LocalAddr != nil {
switch network {
case "tcp":
dialer = &net.Dialer{LocalAddr: &net.TCPAddr{IP: opt.LocalAddr}}
case "udp":
dialer = &net.Dialer{LocalAddr: &net.UDPAddr{IP: opt.LocalAddr}}
}
}
client := &dns.Client{
Net: network,
Dialer: dialer,
TLSConfig: &tls.Config{},
UDPSize: 4096,
}
return &DNSClient{
id: id,
net: network,
endpoint: endpoint,
pipeline: NewPipeline(id, endpoint, client),
}, nil
}
// Resolve a DNS query.
func (d *DNSClient) Resolve(q *dns.Msg, ci ClientInfo) (*dns.Msg, error) {
logger(d.id, q, ci).WithFields(logrus.Fields{
"resolver": d.endpoint,
"protocol": d.net,
}).Debug("querying upstream resolver")
// Remove padding before sending over the wire in plain
stripPadding(q)
return d.pipeline.Resolve(q)
}
func (d *DNSClient) String() string {
return d.id
}