sing-box/dns/transport_local.go

80 lines
1.7 KiB
Go
Raw Normal View History

2022-07-06 10:48:11 +00:00
package dns
import (
"context"
"net"
"net/netip"
"os"
"sort"
2022-07-06 15:11:48 +00:00
"github.com/sagernet/sing-box/adapter"
2022-07-06 10:48:11 +00:00
C "github.com/sagernet/sing-box/constant"
2022-07-08 15:03:57 +00:00
"github.com/sagernet/sing/common"
2022-07-06 10:48:11 +00:00
"golang.org/x/net/dns/dnsmessage"
)
2022-07-06 15:11:48 +00:00
var LocalTransportConstructor func() adapter.DNSTransport
2022-07-06 10:48:11 +00:00
2022-07-06 15:11:48 +00:00
func NewLocalTransport() adapter.DNSTransport {
2022-07-06 10:48:11 +00:00
if LocalTransportConstructor != nil {
return LocalTransportConstructor()
}
return &LocalTransport{}
}
2022-07-06 15:11:48 +00:00
var _ adapter.DNSTransport = (*LocalTransport)(nil)
2022-07-06 10:48:11 +00:00
type LocalTransport struct {
resolver net.Resolver
}
func (t *LocalTransport) Start() error {
return nil
}
func (t *LocalTransport) Close() error {
return nil
}
func (t *LocalTransport) Raw() bool {
return false
}
func (t *LocalTransport) Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error) {
return nil, os.ErrInvalid
}
func (t *LocalTransport) Lookup(ctx context.Context, domain string, strategy C.DomainStrategy) ([]netip.Addr, error) {
var network string
switch strategy {
case C.DomainStrategyAsIS, C.DomainStrategyPreferIPv4, C.DomainStrategyPreferIPv6:
network = "ip"
case C.DomainStrategyUseIPv4:
network = "ip4"
case C.DomainStrategyUseIPv6:
network = "ip6"
}
addrs, err := t.resolver.LookupNetIP(ctx, network, domain)
if err != nil {
return nil, err
}
addrs = common.Map(addrs, func(it netip.Addr) netip.Addr {
if it.Is4In6() {
return netip.AddrFrom4(it.As4())
}
return it
})
switch strategy {
case C.DomainStrategyPreferIPv4:
sort.Slice(addrs, func(i, j int) bool {
return addrs[i].Is4() && addrs[j].Is6()
})
case C.DomainStrategyPreferIPv6:
sort.Slice(addrs, func(i, j int) bool {
return addrs[i].Is6() && addrs[j].Is4()
})
}
return addrs, nil
}