refactor: DNS

This commit is contained in:
世界 2025-03-16 14:50:44 +08:00
parent a530e424e9
commit 86116b9423
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
89 changed files with 4792 additions and 1733 deletions

View file

@ -6,7 +6,10 @@ import (
"strings"
"syscall"
"github.com/sagernet/sing-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/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
@ -21,118 +24,80 @@ type LocalDNSTransport interface {
Exchange(ctx *ExchangeContext, message []byte) error
}
func RegisterLocalDNSTransport(transport LocalDNSTransport) {
if transport == nil {
dns.RegisterTransport([]string{"local"}, func(options dns.TransportOptions) (dns.Transport, error) {
return dns.NewLocalTransport(options), nil
})
} else {
dns.RegisterTransport([]string{"local"}, func(options dns.TransportOptions) (dns.Transport, error) {
return &platformLocalDNSTransport{
iif: transport,
}, nil
})
}
}
var _ adapter.DNSTransport = (*platformTransport)(nil)
var _ dns.Transport = (*platformLocalDNSTransport)(nil)
type platformLocalDNSTransport struct {
type platformTransport struct {
dns.TransportAdapter
iif LocalDNSTransport
}
func (p *platformLocalDNSTransport) Name() string {
return "local"
}
func (p *platformLocalDNSTransport) Start() error {
return nil
}
func (p *platformLocalDNSTransport) Reset() {
}
func (p *platformLocalDNSTransport) Close() error {
return nil
}
func (p *platformLocalDNSTransport) Raw() bool {
return p.iif.Raw()
}
func (p *platformLocalDNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
messageBytes, err := message.Pack()
if err != nil {
return nil, err
func newPlatformTransport(iif LocalDNSTransport, tag string, options option.LocalDNSServerOptions) *platformTransport {
return &platformTransport{
TransportAdapter: dns.NewTransportAdapterWithLocalOptions(C.DNSTypeLocal, tag, options),
iif: iif,
}
}
func (p *platformTransport) Reset() {
}
func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
response := &ExchangeContext{
context: ctx,
}
var responseMessage *mDNS.Msg
var group task.Group
group.Append0(func(ctx context.Context) error {
err = p.iif.Exchange(response, messageBytes)
if p.iif.Raw() {
messageBytes, err := message.Pack()
if err != nil {
return err
return nil, err
}
if response.error != nil {
return response.error
}
responseMessage = &response.message
return nil
})
err = group.Run(ctx)
if err != nil {
return nil, err
}
return responseMessage, nil
}
func (p *platformLocalDNSTransport) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) {
var network string
switch strategy {
case dns.DomainStrategyUseIPv4:
network = "ip4"
case dns.DomainStrategyPreferIPv6:
network = "ip6"
default:
network = "ip"
}
response := &ExchangeContext{
context: ctx,
}
var responseAddr []netip.Addr
var group task.Group
group.Append0(func(ctx context.Context) error {
err := p.iif.Lookup(response, network, domain)
var responseMessage *mDNS.Msg
var group task.Group
group.Append0(func(ctx context.Context) error {
err = p.iif.Exchange(response, messageBytes)
if err != nil {
return err
}
if response.error != nil {
return response.error
}
responseMessage = &response.message
return nil
})
err = group.Run(ctx)
if err != nil {
return err
return nil, err
}
if response.error != nil {
return response.error
}
switch strategy {
case dns.DomainStrategyUseIPv4:
responseAddr = common.Filter(response.addresses, func(it netip.Addr) bool {
return it.Is4()
})
case dns.DomainStrategyPreferIPv6:
responseAddr = common.Filter(response.addresses, func(it netip.Addr) bool {
return it.Is6()
})
return responseMessage, nil
} else {
question := message.Question[0]
var network string
switch question.Qtype {
case mDNS.TypeA:
network = "ip4"
case mDNS.TypeAAAA:
network = "ip6"
default:
responseAddr = response.addresses
return nil, E.New("only IP queries are supported by current version of Android")
}
/*if len(responseAddr) == 0 {
response.error = dns.RCodeSuccess
}*/
return nil
})
err := group.Run(ctx)
if err != nil {
return nil, err
var responseAddrs []netip.Addr
var group task.Group
group.Append0(func(ctx context.Context) error {
err := p.iif.Lookup(response, network, question.Name)
if err != nil {
return err
}
if response.error != nil {
return response.error
}
responseAddrs = response.addresses
return nil
})
err := group.Run(ctx)
if err != nil {
return nil, err
}
return dns.FixedResponse(message.Id, question, responseAddrs, C.DefaultDNSTTL), nil
}
return responseAddr, nil
}
type Func interface {