mirror of
https://github.com/MetaCubeX/Clash.Meta.git
synced 2025-04-16 15:30:55 +00:00
chore: cleanup resolveUDPAddr code
This commit is contained in:
parent
8752f80595
commit
b2d2890866
9 changed files with 31 additions and 71 deletions
|
@ -78,7 +78,7 @@ func (h *Hysteria) genHdc(ctx context.Context, opts ...dialer.Option) utils.Pack
|
||||||
return cDialer.ListenPacket(ctx, network, "", rAddrPort)
|
return cDialer.ListenPacket(ctx, network, "", rAddrPort)
|
||||||
},
|
},
|
||||||
remoteAddr: func(addr string) (net.Addr, error) {
|
remoteAddr: func(addr string) (net.Addr, error) {
|
||||||
return resolveUDPAddrWithPrefer(ctx, "udp", addr, h.prefer)
|
return resolveUDPAddr(ctx, "udp", addr, h.prefer)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||||
CWND: option.CWND,
|
CWND: option.CWND,
|
||||||
UdpMTU: option.UdpMTU,
|
UdpMTU: option.UdpMTU,
|
||||||
ServerAddress: func(ctx context.Context) (*net.UDPAddr, error) {
|
ServerAddress: func(ctx context.Context) (*net.UDPAddr, error) {
|
||||||
return resolveUDPAddrWithPrefer(ctx, "udp", addr, C.NewDNSPrefer(option.IPVersion))
|
return resolveUDPAddr(ctx, "udp", addr, C.NewDNSPrefer(option.IPVersion))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||||
})
|
})
|
||||||
if len(serverAddress) > 0 {
|
if len(serverAddress) > 0 {
|
||||||
clientOptions.ServerAddress = func(ctx context.Context) (*net.UDPAddr, error) {
|
clientOptions.ServerAddress = func(ctx context.Context) (*net.UDPAddr, error) {
|
||||||
return resolveUDPAddrWithPrefer(ctx, "udp", serverAddress[randv2.IntN(len(serverAddress))], C.NewDNSPrefer(option.IPVersion))
|
return resolveUDPAddr(ctx, "udp", serverAddress[randv2.IntN(len(serverAddress))], C.NewDNSPrefer(option.IPVersion))
|
||||||
}
|
}
|
||||||
|
|
||||||
if option.HopInterval == 0 {
|
if option.HopInterval == 0 {
|
||||||
|
|
|
@ -197,7 +197,7 @@ func (ss *ShadowSocks) ListenPacketWithDialer(ctx context.Context, dialer C.Dial
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ss.addr, ss.prefer)
|
addr, err := resolveUDPAddr(ctx, "udp", ss.addr, ss.prefer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ func (ssr *ShadowSocksR) ListenPacketWithDialer(ctx context.Context, dialer C.Di
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ssr.addr, ssr.prefer)
|
addr, err := resolveUDPAddr(ctx, "udp", ssr.addr, ssr.prefer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ func (ss *Socks5) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
|
||||||
err = errors.New("invalid UDP bind address")
|
err = errors.New("invalid UDP bind address")
|
||||||
return
|
return
|
||||||
} else if bindUDPAddr.IP.IsUnspecified() {
|
} else if bindUDPAddr.IP.IsUnspecified() {
|
||||||
serverAddr, err := resolveUDPAddr(ctx, "udp", ss.Addr())
|
serverAddr, err := resolveUDPAddr(ctx, "udp", ss.Addr(), C.IPv4Prefer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (transport *
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
udpAddr, err := resolveUDPAddrWithPrefer(ctx, "udp", t.addr, t.prefer)
|
udpAddr, err := resolveUDPAddr(ctx, "udp", t.addr, t.prefer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,17 @@ package outbound
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/transport/socks5"
|
"github.com/metacubex/mihomo/transport/socks5"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
globalClientSessionCache tls.ClientSessionCache
|
|
||||||
once sync.Once
|
|
||||||
)
|
|
||||||
|
|
||||||
func getClientSessionCache() tls.ClientSessionCache {
|
|
||||||
once.Do(func() {
|
|
||||||
globalClientSessionCache = tls.NewLRUClientSessionCache(128)
|
|
||||||
})
|
|
||||||
return globalClientSessionCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func serializesSocksAddr(metadata *C.Metadata) []byte {
|
func serializesSocksAddr(metadata *C.Metadata) []byte {
|
||||||
var buf [][]byte
|
var buf [][]byte
|
||||||
addrType := metadata.AddrType()
|
addrType := metadata.AddrType()
|
||||||
|
@ -49,67 +35,21 @@ func serializesSocksAddr(metadata *C.Metadata) []byte {
|
||||||
return bytes.Join(buf, nil)
|
return bytes.Join(buf, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveUDPAddr(ctx context.Context, network, address string) (*net.UDPAddr, error) {
|
func resolveUDPAddr(ctx context.Context, network, address string, prefer C.DNSPrefer) (*net.UDPAddr, error) {
|
||||||
host, port, err := net.SplitHostPort(address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ip, err := resolver.ResolveIPWithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return net.ResolveUDPAddr(network, net.JoinHostPort(ip.String(), port))
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolveUDPAddrWithPrefer(ctx context.Context, network, address string, prefer C.DNSPrefer) (*net.UDPAddr, error) {
|
|
||||||
host, port, err := net.SplitHostPort(address)
|
host, port, err := net.SplitHostPort(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var ip netip.Addr
|
var ip netip.Addr
|
||||||
var fallback netip.Addr
|
|
||||||
switch prefer {
|
switch prefer {
|
||||||
case C.IPv4Only:
|
case C.IPv4Only:
|
||||||
ip, err = resolver.ResolveIPv4WithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
ip, err = resolver.ResolveIPv4WithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
||||||
case C.IPv6Only:
|
case C.IPv6Only:
|
||||||
ip, err = resolver.ResolveIPv6WithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
ip, err = resolver.ResolveIPv6WithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
||||||
case C.IPv6Prefer:
|
case C.IPv6Prefer:
|
||||||
var ips []netip.Addr
|
ip, err = resolver.ResolveIPPrefer6WithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
||||||
ips, err = resolver.LookupIPWithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
|
||||||
if err == nil {
|
|
||||||
for _, addr := range ips {
|
|
||||||
if addr.Is6() {
|
|
||||||
ip = addr
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
if !fallback.IsValid() {
|
|
||||||
fallback = addr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
// C.IPv4Prefer, C.DualStack and other
|
ip, err = resolver.ResolveIPWithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
||||||
var ips []netip.Addr
|
|
||||||
ips, err = resolver.LookupIPWithResolver(ctx, host, resolver.ProxyServerHostResolver)
|
|
||||||
if err == nil {
|
|
||||||
for _, addr := range ips {
|
|
||||||
if addr.Is4() {
|
|
||||||
ip = addr
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
if !fallback.IsValid() {
|
|
||||||
fallback = addr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ip.IsValid() && fallback.IsValid() {
|
|
||||||
ip = fallback
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -301,7 +301,7 @@ func (w *WireGuard) resolve(ctx context.Context, address M.Socksaddr) (netip.Add
|
||||||
if address.Addr.IsValid() {
|
if address.Addr.IsValid() {
|
||||||
return address.AddrPort(), nil
|
return address.AddrPort(), nil
|
||||||
}
|
}
|
||||||
udpAddr, err := resolveUDPAddrWithPrefer(ctx, "udp", address.String(), w.prefer)
|
udpAddr, err := resolveUDPAddr(ctx, "udp", address.String(), w.prefer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netip.AddrPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,26 @@ func ResolveIP(ctx context.Context, host string) (netip.Addr, error) {
|
||||||
return ResolveIPWithResolver(ctx, host, DefaultResolver)
|
return ResolveIPWithResolver(ctx, host, DefaultResolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResolveIPPrefer6WithResolver same as ResolveIP, but with a resolver
|
||||||
|
func ResolveIPPrefer6WithResolver(ctx context.Context, host string, r Resolver) (netip.Addr, error) {
|
||||||
|
ips, err := LookupIPWithResolver(ctx, host, r)
|
||||||
|
if err != nil {
|
||||||
|
return netip.Addr{}, err
|
||||||
|
} else if len(ips) == 0 {
|
||||||
|
return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host)
|
||||||
|
}
|
||||||
|
ipv4s, ipv6s := SortationAddr(ips)
|
||||||
|
if len(ipv6s) > 0 {
|
||||||
|
return ipv6s[randv2.IntN(len(ipv6s))], nil
|
||||||
|
}
|
||||||
|
return ipv4s[randv2.IntN(len(ipv4s))], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolveIPPrefer6 with a host, return ip and priority return TypeAAAA
|
||||||
|
func ResolveIPPrefer6(ctx context.Context, host string) (netip.Addr, error) {
|
||||||
|
return ResolveIPPrefer6WithResolver(ctx, host, DefaultResolver)
|
||||||
|
}
|
||||||
|
|
||||||
func ResetConnection() {
|
func ResetConnection() {
|
||||||
if DefaultResolver != nil {
|
if DefaultResolver != nil {
|
||||||
go DefaultResolver.ResetConnection()
|
go DefaultResolver.ResetConnection()
|
||||||
|
|
Loading…
Add table
Reference in a new issue