86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package dnscrypt
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/afonsofrancof/sdns-proxy/common/logger"
|
|
"github.com/ameshkov/dnscrypt/v2"
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
type Config struct {
|
|
ServerStamp string
|
|
DNSSEC bool
|
|
WriteTimeout time.Duration
|
|
ReadTimeout time.Duration
|
|
}
|
|
|
|
type Client struct {
|
|
resolver *dnscrypt.Client
|
|
config Config
|
|
ri *dnscrypt.ResolverInfo
|
|
}
|
|
|
|
func New(config Config) (*Client, error) {
|
|
logger.Debug("Creating DNSCrypt client with stamp: %s", config.ServerStamp)
|
|
|
|
if config.ServerStamp == "" {
|
|
logger.Error("DNSCrypt client creation failed: empty ServerStamp")
|
|
return nil, fmt.Errorf("dnscrypt: ServerStamp cannot be empty")
|
|
}
|
|
if config.WriteTimeout <= 0 {
|
|
config.WriteTimeout = 5 * time.Second
|
|
}
|
|
if config.ReadTimeout <= 0 {
|
|
config.ReadTimeout = 10 * time.Second
|
|
}
|
|
|
|
resolver := &dnscrypt.Client{
|
|
Net: "udp",
|
|
Timeout: config.ReadTimeout,
|
|
}
|
|
|
|
// Resolve the server info from the stamp
|
|
ri, err := resolver.Dial(config.ServerStamp)
|
|
if err != nil {
|
|
logger.Error("DNSCrypt failed to dial server: %v", err)
|
|
return nil, fmt.Errorf("dnscrypt: failed to dial server: %w", err)
|
|
}
|
|
|
|
logger.Debug("DNSCrypt client created (DNSSEC: %v)", config.DNSSEC)
|
|
|
|
return &Client{
|
|
resolver: resolver,
|
|
config: config,
|
|
ri: ri,
|
|
}, nil
|
|
}
|
|
|
|
func (c *Client) Close() {
|
|
// The dnscrypt library doesn't require explicit cleanup
|
|
}
|
|
|
|
func (c *Client) Query(msg *dns.Msg) (*dns.Msg, error) {
|
|
if len(msg.Question) > 0 {
|
|
question := msg.Question[0]
|
|
logger.Debug("DNSCrypt query: %s %s", question.Name, dns.TypeToString[question.Qtype])
|
|
}
|
|
|
|
if c.config.DNSSEC {
|
|
msg.SetEdns0(4096, true)
|
|
}
|
|
|
|
response, err := c.resolver.Exchange(msg, c.ri)
|
|
if err != nil {
|
|
logger.Error("DNSCrypt query failed: %v", err)
|
|
return nil, fmt.Errorf("dnscrypt: query failed: %w", err)
|
|
}
|
|
|
|
if len(response.Answer) > 0 {
|
|
logger.Debug("DNSCrypt response: %d answers", len(response.Answer))
|
|
}
|
|
|
|
return response, nil
|
|
}
|