切换为默认的dns解析;增加resolver=system的支持

This commit is contained in:
wenyifan
2026-07-02 20:50:24 +08:00
parent a24d79fd45
commit bf85966600
6 changed files with 312 additions and 24 deletions
+108
View File
@@ -0,0 +1,108 @@
package exchanger
import (
"context"
"errors"
"net"
"strings"
"time"
"github.com/miekg/dns"
)
type systemExchanger struct {
rawAddr string
timeout time.Duration
lookupIP func(ctx context.Context, network, host string) ([]net.IP, error)
}
func newSystemExchanger(rawAddr string, opts Options) Exchanger {
if opts.timeout <= 0 {
opts.timeout = 5 * time.Second
}
ex := &systemExchanger{
rawAddr: rawAddr,
timeout: opts.timeout,
}
ex.lookupIP = net.DefaultResolver.LookupIP
return ex
}
func (ex *systemExchanger) Exchange(ctx context.Context, msg []byte) ([]byte, error) {
mq := new(dns.Msg)
if err := mq.Unpack(msg); err != nil {
return nil, err
}
mr := new(dns.Msg)
mr.SetReply(mq)
mr.RecursionAvailable = true
if len(mq.Question) == 0 {
return mr.Pack()
}
q := mq.Question[0]
network := "ip"
switch q.Qtype {
case dns.TypeA:
network = "ip4"
case dns.TypeAAAA:
network = "ip6"
default:
return mr.Pack()
}
if ex.timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, ex.timeout)
defer cancel()
}
host := strings.TrimSuffix(q.Name, ".")
ips, err := ex.lookupIP(ctx, network, host)
if err != nil {
var dnsErr *net.DNSError
if !errors.As(err, &dnsErr) || !dnsErr.IsNotFound {
return nil, err
}
}
for _, ip := range ips {
switch q.Qtype {
case dns.TypeA:
if ip4 := ip.To4(); ip4 != nil {
mr.Answer = append(mr.Answer, &dns.A{
Hdr: dns.RR_Header{
Name: q.Name,
Rrtype: dns.TypeA,
Class: q.Qclass,
},
A: ip4,
})
}
case dns.TypeAAAA:
if ip.To4() == nil {
if ip16 := ip.To16(); ip16 != nil {
mr.Answer = append(mr.Answer, &dns.AAAA{
Hdr: dns.RR_Header{
Name: q.Name,
Rrtype: dns.TypeAAAA,
Class: q.Qclass,
},
AAAA: ip16,
})
}
}
}
}
return mr.Pack()
}
func (ex *systemExchanger) String() string {
if ex.rawAddr == "" {
return "system"
}
return ex.rawAddr
}