Files
sing-box-extended/dns/transport/sdns.go
2026-03-10 04:25:01 +03:00

74 lines
1.7 KiB
Go

package transport
import (
"context"
"net"
"sync"
"time"
"github.com/ameshkov/dnscrypt/v2"
mDNS "github.com/miekg/dns"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
var _ adapter.DNSTransport = (*SDNSTransport)(nil)
func RegisterSDNS(registry *dns.TransportRegistry) {
dns.RegisterTransport[option.SDNSDNSServerOptions](registry, C.DNSTypeSDNS, NewSDNSTransport)
}
type SDNSTransport struct {
dns.TransportAdapter
client *dnscrypt.Client
name string
stamp string
mtx sync.Mutex
}
func NewSDNSTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.SDNSDNSServerOptions) (adapter.DNSTransport, error) {
transportDialer, err := dns.NewRemoteDialer(ctx, options.RemoteDNSServerOptions)
if err != nil {
return nil, err
}
return &SDNSTransport{
client: &dnscrypt.Client{
Net: "udp",
Timeout: 10 * time.Second,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return transportDialer.DialContext(ctx, N.NetworkName(network), M.ParseSocksaddr(addr))
},
},
stamp: options.Stamp,
}, err
}
func (t *SDNSTransport) Name() string {
return t.name
}
func (t *SDNSTransport) Start(adapter.StartStage) error {
return nil
}
func (t *SDNSTransport) Close() error {
return nil
}
func (t *SDNSTransport) Reset() {
}
func (t *SDNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
resolverInfo, err := t.client.Dial(t.stamp)
if err != nil {
return nil, err
}
return t.client.Exchange(message, resolverInfo)
}