-
Notifications
You must be signed in to change notification settings - Fork 28
/
transport_local.go
95 lines (81 loc) · 2.03 KB
/
transport_local.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package dns
import (
"context"
"net"
"net/netip"
"os"
"sort"
"github.com/sagernet/sing/common"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/miekg/dns"
)
func init() {
RegisterTransport([]string{"local"}, func(options TransportOptions) (Transport, error) {
return NewLocalTransport(options), nil
})
}
var _ Transport = (*LocalTransport)(nil)
type LocalTransport struct {
name string
resolver net.Resolver
}
func NewLocalTransport(options TransportOptions) *LocalTransport {
return &LocalTransport{
name: options.Name,
resolver: net.Resolver{
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
return options.Dialer.DialContext(ctx, N.NetworkName(network), M.ParseSocksaddr(address))
},
},
}
}
func (t *LocalTransport) Name() string {
return t.name
}
func (t *LocalTransport) Start() error {
return nil
}
func (t *LocalTransport) Reset() {
}
func (t *LocalTransport) Close() error {
return nil
}
func (t *LocalTransport) Raw() bool {
return false
}
func (t *LocalTransport) Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error) {
return nil, os.ErrInvalid
}
func (t *LocalTransport) Lookup(ctx context.Context, domain string, strategy DomainStrategy) ([]netip.Addr, error) {
var network string
switch strategy {
case DomainStrategyAsIS, DomainStrategyPreferIPv4, DomainStrategyPreferIPv6:
network = "ip"
case DomainStrategyUseIPv4:
network = "ip4"
case 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 DomainStrategyPreferIPv4:
sort.Slice(addrs, func(i, j int) bool {
return addrs[i].Is4() && addrs[j].Is6()
})
case DomainStrategyPreferIPv6:
sort.Slice(addrs, func(i, j int) bool {
return addrs[i].Is6() && addrs[j].Is4()
})
}
return addrs, nil
}