Compare commits
5 Commits
v1.12.2_tu
...
v1.12.3_tu
Author | SHA1 | Date | |
---|---|---|---|
e1fe8ce3b2 | |||
b9ee4b902f | |||
7731a684b1 | |||
1f12ef069b | |||
e31be4edc2 |
@ -152,7 +152,7 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
|||||||
func (v *Vless) StreamPacketConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
func (v *Vless) StreamPacketConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||||
// vmess use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
// vmess use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
ip, err := resolver.ResolveIP(metadata.Host)
|
ip, err := resolver.ResolveFirstIP(metadata.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("can't resolve ip")
|
return nil, errors.New("can't resolve ip")
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ func (v *Vless) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
|||||||
if v.transport != nil && len(opts) == 0 {
|
if v.transport != nil && len(opts) == 0 {
|
||||||
// vless use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
// vless use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
ip, err := resolver.ResolveIP(metadata.Host)
|
ip, err := resolver.ResolveFirstIP(metadata.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("can't resolve ip")
|
return nil, errors.New("can't resolve ip")
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
|||||||
func (v *Vmess) StreamPacketConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
func (v *Vmess) StreamPacketConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||||
// vmess use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
// vmess use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
ip, err := resolver.ResolveIP(metadata.Host)
|
ip, err := resolver.ResolveFirstIP(metadata.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c, fmt.Errorf("can't resolve ip: %w", err)
|
return c, fmt.Errorf("can't resolve ip: %w", err)
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
|||||||
if v.transport != nil && len(opts) == 0 {
|
if v.transport != nil && len(opts) == 0 {
|
||||||
// vmess use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
// vmess use stream-oriented udp with a special address, so we needs a net.UDPAddr
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
ip, err := resolver.ResolveIP(metadata.Host)
|
ip, err := resolver.ResolveFirstIP(metadata.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't resolve ip: %w", err)
|
return nil, fmt.Errorf("can't resolve ip: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package outboundgroup
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/adapter"
|
||||||
|
"github.com/Dreamacro/clash/adapter/outbound"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/constant/provider"
|
"github.com/Dreamacro/clash/constant/provider"
|
||||||
)
|
)
|
||||||
@ -11,14 +13,19 @@ const (
|
|||||||
defaultGetProxiesDuration = time.Second * 5
|
defaultGetProxiesDuration = time.Second * 5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var defaultRejectProxy = adapter.NewProxy(outbound.NewReject())
|
||||||
|
|
||||||
func getProvidersProxies(providers []provider.ProxyProvider, touch bool) []C.Proxy {
|
func getProvidersProxies(providers []provider.ProxyProvider, touch bool) []C.Proxy {
|
||||||
proxies := []C.Proxy{}
|
proxies := []C.Proxy{}
|
||||||
for _, provider := range providers {
|
for _, pd := range providers {
|
||||||
if touch {
|
if touch {
|
||||||
proxies = append(proxies, provider.ProxiesWithTouch()...)
|
proxies = append(proxies, pd.ProxiesWithTouch()...)
|
||||||
} else {
|
} else {
|
||||||
proxies = append(proxies, provider.Proxies()...)
|
proxies = append(proxies, pd.Proxies()...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(proxies) == 0 {
|
||||||
|
proxies = append(proxies, defaultRejectProxy)
|
||||||
|
}
|
||||||
return proxies
|
return proxies
|
||||||
}
|
}
|
||||||
|
@ -78,30 +78,18 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
|
|||||||
return nil, errDuplicateProvider
|
return nil, errDuplicateProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// select don't need health check
|
hc, err := newHealthCheck(ps, groupOption)
|
||||||
if groupOption.Type == "select" || groupOption.Type == "relay" {
|
if err != nil {
|
||||||
hc := provider.NewHealthCheck(ps, "", 0, true)
|
return nil, err
|
||||||
pd, err := provider.NewCompatibleProvider(groupName, ps, hc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
providers = append(providers, pd)
|
|
||||||
providersMap[groupName] = pd
|
|
||||||
} else {
|
|
||||||
if groupOption.URL == "" || groupOption.Interval == 0 {
|
|
||||||
return nil, errMissHealthCheck
|
|
||||||
}
|
|
||||||
|
|
||||||
hc := provider.NewHealthCheck(ps, groupOption.URL, uint(groupOption.Interval), groupOption.Lazy)
|
|
||||||
pd, err := provider.NewCompatibleProvider(groupName, ps, hc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
providers = append(providers, pd)
|
|
||||||
providersMap[groupName] = pd
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pd, err := provider.NewCompatibleProvider(groupName, ps, hc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
providers = append(providers, pd)
|
||||||
|
providersMap[groupName] = pd
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(groupOption.Use) != 0 {
|
if len(groupOption.Use) != 0 {
|
||||||
@ -109,7 +97,12 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
providers = append(providers, list...)
|
|
||||||
|
if groupOption.Type == "fallback" {
|
||||||
|
providers = append(list, providers...)
|
||||||
|
} else {
|
||||||
|
providers = append(providers, list...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var group C.ProxyAdapter
|
var group C.ProxyAdapter
|
||||||
@ -163,22 +156,18 @@ func getProviders(mapping map[string]types.ProxyProvider, groupOption *GroupComm
|
|||||||
}
|
}
|
||||||
|
|
||||||
if filterRegx != nil {
|
if filterRegx != nil {
|
||||||
var hc *provider.HealthCheck
|
hc, err := newHealthCheck([]C.Proxy{}, groupOption)
|
||||||
if groupOption.Type == "select" || groupOption.Type == "relay" {
|
if err != nil {
|
||||||
hc = provider.NewHealthCheck([]C.Proxy{}, "", 0, true)
|
return nil, err
|
||||||
} else {
|
|
||||||
if groupOption.URL == "" || groupOption.Interval == 0 {
|
|
||||||
return nil, errMissHealthCheck
|
|
||||||
}
|
|
||||||
hc = provider.NewHealthCheck([]C.Proxy{}, groupOption.URL, uint(groupOption.Interval), groupOption.Lazy)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok = mapping[groupName]; ok {
|
gName := groupName
|
||||||
groupName += "->" + p.Name()
|
if _, ok = mapping[gName]; ok {
|
||||||
|
gName = groupName + " -> " + p.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pd := p.(*provider.ProxySetProvider)
|
pd := p.(*provider.ProxySetProvider)
|
||||||
p = provider.NewProxyFilterProvider(groupName, pd, hc, filterRegx)
|
p = provider.NewProxyFilterProvider(gName, pd, hc, filterRegx)
|
||||||
pd.RegisterProvidersInUse(p)
|
pd.RegisterProvidersInUse(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,3 +175,18 @@ func getProviders(mapping map[string]types.ProxyProvider, groupOption *GroupComm
|
|||||||
}
|
}
|
||||||
return ps, nil
|
return ps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newHealthCheck(ps []C.Proxy, groupOption *GroupCommonOption) (*provider.HealthCheck, error) {
|
||||||
|
var hc *provider.HealthCheck
|
||||||
|
|
||||||
|
// select don't need health check
|
||||||
|
if groupOption.Type == "select" || groupOption.Type == "relay" {
|
||||||
|
hc = provider.NewHealthCheck(ps, "", 0, true)
|
||||||
|
} else {
|
||||||
|
if groupOption.URL == "" || groupOption.Interval == 0 {
|
||||||
|
return nil, errMissHealthCheck
|
||||||
|
}
|
||||||
|
hc = provider.NewHealthCheck(ps, groupOption.URL, uint(groupOption.Interval), groupOption.Lazy)
|
||||||
|
}
|
||||||
|
return hc, nil
|
||||||
|
}
|
||||||
|
@ -98,7 +98,11 @@ func (s *Selector) selectedProxy(touch bool) C.Proxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSelector(option *GroupCommonOption, providers []provider.ProxyProvider) *Selector {
|
func NewSelector(option *GroupCommonOption, providers []provider.ProxyProvider) *Selector {
|
||||||
selected := providers[0].Proxies()[0].Name()
|
selected := "REJECT"
|
||||||
|
if len(providers) != 0 && len(providers[0].Proxies()) != 0 {
|
||||||
|
selected = providers[0].Proxies()[0].Name()
|
||||||
|
}
|
||||||
|
|
||||||
return &Selector{
|
return &Selector{
|
||||||
Base: outbound.NewBase(outbound.BaseOption{
|
Base: outbound.NewBase(outbound.BaseOption{
|
||||||
Name: option.Name,
|
Name: option.Name,
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
func ParseProxy(mapping map[string]any, forceCertVerify bool) (C.Proxy, error) {
|
func ParseProxy(mapping map[string]any, forceCertVerify bool) (C.Proxy, error) {
|
||||||
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
|
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
|
||||||
proxyType, existType := mapping["type"].(string)
|
proxyType, existType := mapping["type"]
|
||||||
if !existType {
|
if !existType {
|
||||||
return nil, fmt.Errorf("missing type")
|
return nil, fmt.Errorf("missing type")
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ func ParseProxy(mapping map[string]any, forceCertVerify bool) (C.Proxy, error) {
|
|||||||
proxy C.ProxyAdapter
|
proxy C.ProxyAdapter
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
switch proxyType {
|
switch proxyType.(string) {
|
||||||
case "ss":
|
case "ss":
|
||||||
ssOption := &outbound.ShadowSocksOption{}
|
ssOption := &outbound.ShadowSocksOption{}
|
||||||
err = decoder.Decode(mapping, ssOption)
|
err = decoder.Decode(mapping, ssOption)
|
||||||
|
@ -25,10 +25,16 @@ type HealthCheck struct {
|
|||||||
interval uint
|
interval uint
|
||||||
lazy bool
|
lazy bool
|
||||||
lastTouch *atomic.Int64
|
lastTouch *atomic.Int64
|
||||||
|
running *atomic.Bool
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *HealthCheck) process() {
|
func (hc *HealthCheck) process() {
|
||||||
|
if hc.running.Load() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hc.running.Store(true)
|
||||||
|
|
||||||
ticker := time.NewTicker(time.Duration(hc.interval) * time.Second)
|
ticker := time.NewTicker(time.Duration(hc.interval) * time.Second)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -84,6 +90,10 @@ func (hc *HealthCheck) check() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (hc *HealthCheck) close() {
|
func (hc *HealthCheck) close() {
|
||||||
|
if !hc.running.Load() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hc.running.Store(false)
|
||||||
hc.done <- struct{}{}
|
hc.done <- struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +104,7 @@ func NewHealthCheck(proxies []C.Proxy, url string, interval uint, lazy bool) *He
|
|||||||
interval: interval,
|
interval: interval,
|
||||||
lazy: lazy,
|
lazy: lazy,
|
||||||
lastTouch: atomic.NewInt64(0),
|
lastTouch: atomic.NewInt64(0),
|
||||||
|
running: atomic.NewBool(false),
|
||||||
done: make(chan struct{}, 1),
|
done: make(chan struct{}, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,9 @@ func (pf *proxyFilterProvider) HealthCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pf *proxyFilterProvider) Update() error {
|
func (pf *proxyFilterProvider) Update() error {
|
||||||
var proxies []C.Proxy
|
pf.healthCheck.close()
|
||||||
|
|
||||||
|
proxies := []C.Proxy{}
|
||||||
if pf.filter != nil {
|
if pf.filter != nil {
|
||||||
for _, proxy := range pf.psd.Proxies() {
|
for _, proxy := range pf.psd.Proxies() {
|
||||||
if !pf.filter.MatchString(proxy.Name()) {
|
if !pf.filter.MatchString(proxy.Name()) {
|
||||||
@ -248,6 +250,10 @@ func (pf *proxyFilterProvider) Update() error {
|
|||||||
|
|
||||||
pf.proxies = proxies
|
pf.proxies = proxies
|
||||||
pf.healthCheck.setProxy(proxies)
|
pf.healthCheck.setProxy(proxies)
|
||||||
|
|
||||||
|
if len(proxies) != 0 && pf.healthCheck.auto() {
|
||||||
|
go pf.healthCheck.process()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,10 +292,6 @@ func NewProxyFilterProvider(name string, psd *ProxySetProvider, hc *HealthCheck,
|
|||||||
|
|
||||||
_ = pd.Update()
|
_ = pd.Update()
|
||||||
|
|
||||||
if hc.auto() {
|
|
||||||
go hc.process()
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapper := &ProxyFilterProvider{pd}
|
wrapper := &ProxyFilterProvider{pd}
|
||||||
runtime.SetFinalizer(wrapper, stopProxyFilterProvider)
|
runtime.SetFinalizer(wrapper, stopProxyFilterProvider)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
@ -28,6 +28,9 @@ func ShouldFindProcess(metadata *C.Metadata) bool {
|
|||||||
if metadata.Process != "" {
|
if metadata.Process != "" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if metadata.SrcIP.IsUnspecified() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
for _, ip := range localIPs {
|
for _, ip := range localIPs {
|
||||||
if ip == metadata.SrcIP {
|
if ip == metadata.SrcIP {
|
||||||
return true
|
return true
|
||||||
@ -41,7 +44,7 @@ func AppendLocalIPs(ip ...netip.Addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getLocalIPs() []netip.Addr {
|
func getLocalIPs() []netip.Addr {
|
||||||
ips := []netip.Addr{netip.IPv4Unspecified(), netip.IPv6Unspecified()}
|
var ips []netip.Addr
|
||||||
|
|
||||||
netInterfaces, err := net.Interfaces()
|
netInterfaces, err := net.Interfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -37,17 +37,17 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Resolver interface {
|
type Resolver interface {
|
||||||
ResolveIP(host string) (ip netip.Addr, err error)
|
ResolveIP(host string, random bool) (ip netip.Addr, err error)
|
||||||
ResolveIPv4(host string) (ip netip.Addr, err error)
|
ResolveIPv4(host string, random bool) (ip netip.Addr, err error)
|
||||||
ResolveIPv6(host string) (ip netip.Addr, err error)
|
ResolveIPv6(host string, random bool) (ip netip.Addr, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveIPv4 with a host, return ipv4
|
// ResolveIPv4 with a host, return ipv4
|
||||||
func ResolveIPv4(host string) (netip.Addr, error) {
|
func ResolveIPv4(host string) (netip.Addr, error) {
|
||||||
return ResolveIPv4WithResolver(host, DefaultResolver)
|
return resolveIPv4(host, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveIPv4WithResolver(host string, r Resolver) (netip.Addr, error) {
|
func ResolveIPv4WithResolver(host string, r Resolver, random bool) (netip.Addr, error) {
|
||||||
if node := DefaultHosts.Search(host); node != nil {
|
if node := DefaultHosts.Search(host); node != nil {
|
||||||
if ip := node.Data; ip.Is4() {
|
if ip := node.Data; ip.Is4() {
|
||||||
return ip, nil
|
return ip, nil
|
||||||
@ -56,6 +56,7 @@ func ResolveIPv4WithResolver(host string, r Resolver) (netip.Addr, error) {
|
|||||||
|
|
||||||
ip, err := netip.ParseAddr(host)
|
ip, err := netip.ParseAddr(host)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
ip = ip.Unmap()
|
||||||
if ip.Is4() {
|
if ip.Is4() {
|
||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
@ -63,7 +64,7 @@ func ResolveIPv4WithResolver(host string, r Resolver) (netip.Addr, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r != nil {
|
if r != nil {
|
||||||
return r.ResolveIPv4(host)
|
return r.ResolveIPv4(host, random)
|
||||||
}
|
}
|
||||||
|
|
||||||
if DefaultResolver == nil {
|
if DefaultResolver == nil {
|
||||||
@ -76,7 +77,11 @@ func ResolveIPv4WithResolver(host string, r Resolver) (netip.Addr, error) {
|
|||||||
return netip.Addr{}, ErrIPNotFound
|
return netip.Addr{}, ErrIPNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
ip := ipAddrs[rand.Intn(len(ipAddrs))].To4()
|
index := 0
|
||||||
|
if random {
|
||||||
|
index = rand.Intn(len(ipAddrs))
|
||||||
|
}
|
||||||
|
ip := ipAddrs[index].To4()
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return netip.Addr{}, ErrIPVersion
|
return netip.Addr{}, ErrIPVersion
|
||||||
}
|
}
|
||||||
@ -89,10 +94,10 @@ func ResolveIPv4WithResolver(host string, r Resolver) (netip.Addr, error) {
|
|||||||
|
|
||||||
// ResolveIPv6 with a host, return ipv6
|
// ResolveIPv6 with a host, return ipv6
|
||||||
func ResolveIPv6(host string) (netip.Addr, error) {
|
func ResolveIPv6(host string) (netip.Addr, error) {
|
||||||
return ResolveIPv6WithResolver(host, DefaultResolver)
|
return ResolveIPv6WithResolver(host, DefaultResolver, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveIPv6WithResolver(host string, r Resolver) (netip.Addr, error) {
|
func ResolveIPv6WithResolver(host string, r Resolver, random bool) (netip.Addr, error) {
|
||||||
if DisableIPv6 {
|
if DisableIPv6 {
|
||||||
return netip.Addr{}, ErrIPv6Disabled
|
return netip.Addr{}, ErrIPv6Disabled
|
||||||
}
|
}
|
||||||
@ -112,7 +117,7 @@ func ResolveIPv6WithResolver(host string, r Resolver) (netip.Addr, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r != nil {
|
if r != nil {
|
||||||
return r.ResolveIPv6(host)
|
return r.ResolveIPv6(host, random)
|
||||||
}
|
}
|
||||||
|
|
||||||
if DefaultResolver == nil {
|
if DefaultResolver == nil {
|
||||||
@ -125,25 +130,29 @@ func ResolveIPv6WithResolver(host string, r Resolver) (netip.Addr, error) {
|
|||||||
return netip.Addr{}, ErrIPNotFound
|
return netip.Addr{}, ErrIPNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return netip.AddrFrom16(*(*[16]byte)(ipAddrs[rand.Intn(len(ipAddrs))])), nil
|
index := 0
|
||||||
|
if random {
|
||||||
|
index = rand.Intn(len(ipAddrs))
|
||||||
|
}
|
||||||
|
return netip.AddrFrom16(*(*[16]byte)(ipAddrs[index])), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return netip.Addr{}, ErrIPNotFound
|
return netip.Addr{}, ErrIPNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveIPWithResolver same as ResolveIP, but with a resolver
|
// ResolveIPWithResolver same as ResolveIP, but with a resolver
|
||||||
func ResolveIPWithResolver(host string, r Resolver) (netip.Addr, error) {
|
func ResolveIPWithResolver(host string, r Resolver, random bool) (netip.Addr, error) {
|
||||||
if node := DefaultHosts.Search(host); node != nil {
|
if node := DefaultHosts.Search(host); node != nil {
|
||||||
return node.Data, nil
|
return node.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if r != nil {
|
if r != nil {
|
||||||
if DisableIPv6 {
|
if DisableIPv6 {
|
||||||
return r.ResolveIPv4(host)
|
return r.ResolveIPv4(host, random)
|
||||||
}
|
}
|
||||||
return r.ResolveIP(host)
|
return r.ResolveIP(host, random)
|
||||||
} else if DisableIPv6 {
|
} else if DisableIPv6 {
|
||||||
return ResolveIPv4(host)
|
return resolveIPv4(host, random)
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := netip.ParseAddr(host)
|
ip, err := netip.ParseAddr(host)
|
||||||
@ -165,13 +174,18 @@ func ResolveIPWithResolver(host string, r Resolver) (netip.Addr, error) {
|
|||||||
|
|
||||||
// ResolveIP with a host, return ip
|
// ResolveIP with a host, return ip
|
||||||
func ResolveIP(host string) (netip.Addr, error) {
|
func ResolveIP(host string) (netip.Addr, error) {
|
||||||
return ResolveIPWithResolver(host, DefaultResolver)
|
return resolveIP(host, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolveFirstIP with a host, return ip
|
||||||
|
func ResolveFirstIP(host string) (netip.Addr, error) {
|
||||||
|
return resolveIP(host, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveIPv4ProxyServerHost proxies server host only
|
// ResolveIPv4ProxyServerHost proxies server host only
|
||||||
func ResolveIPv4ProxyServerHost(host string) (netip.Addr, error) {
|
func ResolveIPv4ProxyServerHost(host string) (netip.Addr, error) {
|
||||||
if ProxyServerHostResolver != nil {
|
if ProxyServerHostResolver != nil {
|
||||||
return ResolveIPv4WithResolver(host, ProxyServerHostResolver)
|
return ResolveIPv4WithResolver(host, ProxyServerHostResolver, true)
|
||||||
}
|
}
|
||||||
return ResolveIPv4(host)
|
return ResolveIPv4(host)
|
||||||
}
|
}
|
||||||
@ -179,7 +193,7 @@ func ResolveIPv4ProxyServerHost(host string) (netip.Addr, error) {
|
|||||||
// ResolveIPv6ProxyServerHost proxies server host only
|
// ResolveIPv6ProxyServerHost proxies server host only
|
||||||
func ResolveIPv6ProxyServerHost(host string) (netip.Addr, error) {
|
func ResolveIPv6ProxyServerHost(host string) (netip.Addr, error) {
|
||||||
if ProxyServerHostResolver != nil {
|
if ProxyServerHostResolver != nil {
|
||||||
return ResolveIPv6WithResolver(host, ProxyServerHostResolver)
|
return ResolveIPv6WithResolver(host, ProxyServerHostResolver, true)
|
||||||
}
|
}
|
||||||
return ResolveIPv6(host)
|
return ResolveIPv6(host)
|
||||||
}
|
}
|
||||||
@ -187,7 +201,15 @@ func ResolveIPv6ProxyServerHost(host string) (netip.Addr, error) {
|
|||||||
// ResolveProxyServerHost proxies server host only
|
// ResolveProxyServerHost proxies server host only
|
||||||
func ResolveProxyServerHost(host string) (netip.Addr, error) {
|
func ResolveProxyServerHost(host string) (netip.Addr, error) {
|
||||||
if ProxyServerHostResolver != nil {
|
if ProxyServerHostResolver != nil {
|
||||||
return ResolveIPWithResolver(host, ProxyServerHostResolver)
|
return ResolveIPWithResolver(host, ProxyServerHostResolver, true)
|
||||||
}
|
}
|
||||||
return ResolveIP(host)
|
return ResolveIP(host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveIP(host string, random bool) (netip.Addr, error) {
|
||||||
|
return ResolveIPWithResolver(host, DefaultResolver, random)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveIPv4(host string, random bool) (netip.Addr, error) {
|
||||||
|
return ResolveIPv4WithResolver(host, DefaultResolver, random)
|
||||||
|
}
|
||||||
|
@ -415,11 +415,11 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
|
|||||||
|
|
||||||
// keep the original order of ProxyGroups in config file
|
// keep the original order of ProxyGroups in config file
|
||||||
for idx, mapping := range groupsConfig {
|
for idx, mapping := range groupsConfig {
|
||||||
groupName, existName := mapping["name"].(string)
|
groupName, existName := mapping["name"]
|
||||||
if !existName {
|
if !existName {
|
||||||
return nil, nil, fmt.Errorf("proxy group %d: missing name", idx)
|
return nil, nil, fmt.Errorf("proxy group %d: missing name", idx)
|
||||||
}
|
}
|
||||||
proxyList = append(proxyList, groupName)
|
proxyList = append(proxyList, groupName.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if any loop exists and sort the ProxyGroups
|
// check if any loop exists and sort the ProxyGroups
|
||||||
|
@ -36,7 +36,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
|||||||
if c.r == nil {
|
if c.r == nil {
|
||||||
return nil, fmt.Errorf("dns %s not a valid ip", c.host)
|
return nil, fmt.Errorf("dns %s not a valid ip", c.host)
|
||||||
} else {
|
} else {
|
||||||
if ip, err = resolver.ResolveIPWithResolver(c.host, c.r); err != nil {
|
if ip, err = resolver.ResolveIPWithResolver(c.host, c.r, true); err != nil {
|
||||||
return nil, fmt.Errorf("use default dns resolve failed: %w", err)
|
return nil, fmt.Errorf("use default dns resolve failed: %w", err)
|
||||||
}
|
}
|
||||||
c.host = ip.String()
|
c.host = ip.String()
|
||||||
|
@ -94,7 +94,7 @@ func newDoHClient(url string, r *Resolver, proxyAdapter string) *dohClient {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := resolver.ResolveIPWithResolver(host, r)
|
ip, err := resolver.ResolveIPWithResolver(host, r, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ import (
|
|||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ resolver.Resolver = (*Resolver)(nil)
|
||||||
|
|
||||||
type dnsClient interface {
|
type dnsClient interface {
|
||||||
Exchange(m *D.Msg) (msg *D.Msg, err error)
|
Exchange(m *D.Msg) (msg *D.Msg, err error)
|
||||||
ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error)
|
ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error)
|
||||||
@ -45,18 +47,18 @@ type Resolver struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ResolveIP request with TypeA and TypeAAAA, priority return TypeA
|
// ResolveIP request with TypeA and TypeAAAA, priority return TypeA
|
||||||
func (r *Resolver) ResolveIP(host string) (ip netip.Addr, err error) {
|
func (r *Resolver) ResolveIP(host string, random bool) (ip netip.Addr, err error) {
|
||||||
ch := make(chan netip.Addr, 1)
|
ch := make(chan netip.Addr, 1)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
ip, err := r.resolveIP(host, D.TypeAAAA)
|
ip, err := r.resolveIP(host, D.TypeAAAA, random)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ch <- ip
|
ch <- ip
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ip, err = r.resolveIP(host, D.TypeA)
|
ip, err = r.resolveIP(host, D.TypeA, random)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -70,13 +72,13 @@ func (r *Resolver) ResolveIP(host string) (ip netip.Addr, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ResolveIPv4 request with TypeA
|
// ResolveIPv4 request with TypeA
|
||||||
func (r *Resolver) ResolveIPv4(host string) (ip netip.Addr, err error) {
|
func (r *Resolver) ResolveIPv4(host string, random bool) (ip netip.Addr, err error) {
|
||||||
return r.resolveIP(host, D.TypeA)
|
return r.resolveIP(host, D.TypeA, random)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveIPv6 request with TypeAAAA
|
// ResolveIPv6 request with TypeAAAA
|
||||||
func (r *Resolver) ResolveIPv6(host string) (ip netip.Addr, err error) {
|
func (r *Resolver) ResolveIPv6(host string, random bool) (ip netip.Addr, err error) {
|
||||||
return r.resolveIP(host, D.TypeAAAA)
|
return r.resolveIP(host, D.TypeAAAA, random)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) shouldIPFallback(ip netip.Addr) bool {
|
func (r *Resolver) shouldIPFallback(ip netip.Addr) bool {
|
||||||
@ -255,9 +257,10 @@ func (r *Resolver) ipExchange(ctx context.Context, m *D.Msg) (msg *D.Msg, err er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) resolveIP(host string, dnsType uint16) (ip netip.Addr, err error) {
|
func (r *Resolver) resolveIP(host string, dnsType uint16, random bool) (ip netip.Addr, err error) {
|
||||||
ip, err = netip.ParseAddr(host)
|
ip, err = netip.ParseAddr(host)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
ip = ip.Unmap()
|
||||||
isIPv4 := ip.Is4()
|
isIPv4 := ip.Is4()
|
||||||
if dnsType == D.TypeAAAA && !isIPv4 {
|
if dnsType == D.TypeAAAA && !isIPv4 {
|
||||||
return ip, nil
|
return ip, nil
|
||||||
@ -282,7 +285,12 @@ func (r *Resolver) resolveIP(host string, dnsType uint16) (ip netip.Addr, err er
|
|||||||
return netip.Addr{}, resolver.ErrIPNotFound
|
return netip.Addr{}, resolver.ErrIPNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = ips[rand.Intn(ipLength)]
|
index := 0
|
||||||
|
if random {
|
||||||
|
index = rand.Intn(ipLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = ips[index]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
go.mod
8
go.mod
@ -9,7 +9,7 @@ require (
|
|||||||
github.com/gofrs/uuid v4.2.0+incompatible
|
github.com/gofrs/uuid v4.2.0+incompatible
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f
|
github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f
|
||||||
github.com/miekg/dns v1.1.49
|
github.com/miekg/dns v1.1.50
|
||||||
github.com/oschwald/geoip2-golang v1.7.0
|
github.com/oschwald/geoip2-golang v1.7.0
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/stretchr/testify v1.7.2
|
github.com/stretchr/testify v1.7.2
|
||||||
@ -17,11 +17,11 @@ require (
|
|||||||
go.etcd.io/bbolt v1.3.6
|
go.etcd.io/bbolt v1.3.6
|
||||||
go.uber.org/atomic v1.9.0
|
go.uber.org/atomic v1.9.0
|
||||||
go.uber.org/automaxprocs v1.5.1
|
go.uber.org/automaxprocs v1.5.1
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d
|
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d
|
||||||
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9
|
golang.org/x/net v0.0.0-20220622184535-263ec571b305
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
|
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
|
||||||
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c
|
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664
|
||||||
golang.org/x/text v0.3.8-0.20220124021120-d1c84af989ab
|
golang.org/x/text v0.3.8-0.20220124021120-d1c84af989ab
|
||||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858
|
golang.org/x/time v0.0.0-20220609170525-579cf78fd858
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20220601130007-6a08d81f6bc4
|
golang.zx2c4.com/wireguard v0.0.0-20220601130007-6a08d81f6bc4
|
||||||
|
16
go.sum
16
go.sum
@ -45,8 +45,8 @@ github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcK
|
|||||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||||
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||||
github.com/miekg/dns v1.1.49 h1:qe0mQU3Z/XpFeE+AEBo2rqaS1IPBJ3anmqZ4XiZJVG8=
|
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||||
github.com/miekg/dns v1.1.49/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||||
github.com/oschwald/geoip2-golang v1.7.0 h1:JW1r5AKi+vv2ujSxjKthySK3jo8w8oKWPyXsw+Qs/S8=
|
github.com/oschwald/geoip2-golang v1.7.0 h1:JW1r5AKi+vv2ujSxjKthySK3jo8w8oKWPyXsw+Qs/S8=
|
||||||
github.com/oschwald/geoip2-golang v1.7.0/go.mod h1:mdI/C7iK7NVMcIDDtf4bCKMJ7r0o7UwGeCo9eiitCMQ=
|
github.com/oschwald/geoip2-golang v1.7.0/go.mod h1:mdI/C7iK7NVMcIDDtf4bCKMJ7r0o7UwGeCo9eiitCMQ=
|
||||||
github.com/oschwald/maxminddb-golang v1.9.0 h1:tIk4nv6VT9OiPyrnDAfJS1s1xKDQMZOsGojab6EjC1Y=
|
github.com/oschwald/maxminddb-golang v1.9.0 h1:tIk4nv6VT9OiPyrnDAfJS1s1xKDQMZOsGojab6EjC1Y=
|
||||||
@ -78,8 +78,8 @@ go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d h1:vtUKgx8dahOomfFzLREU8nSv25YHnTgLBn4rDnWZdU0=
|
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d h1:vtUKgx8dahOomfFzLREU8nSv25YHnTgLBn4rDnWZdU0=
|
||||||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
@ -97,8 +97,8 @@ golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 h1:Yqz/iviulwKwAREEeUd3nbBFn0XuyJqkoft2IlrvOhc=
|
golang.org/x/net v0.0.0-20220622184535-263ec571b305 h1:dAgbJ2SP4jD6XYfMNLVj0BF21jo2PjChrtGaAvF5M3I=
|
||||||
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220622184535-263ec571b305/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
|
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
|
||||||
@ -123,8 +123,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU=
|
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664 h1:wEZYwx+kK+KlZ0hpvP2Ls1Xr4+RWnlzGFwPP0aiDjIU=
|
||||||
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
@ -16,7 +16,7 @@ func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata
|
|||||||
|
|
||||||
// local resolve UDP dns
|
// local resolve UDP dns
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
ip, err := resolver.ResolveIP(metadata.Host)
|
ip, err := resolver.ResolveFirstIP(metadata.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -190,19 +190,6 @@ func preHandleMetadata(metadata *C.Metadata) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pre resolve process name
|
|
||||||
srcPort, err := strconv.ParseUint(metadata.SrcPort, 10, 16)
|
|
||||||
if err == nil && P.ShouldFindProcess(metadata) {
|
|
||||||
path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(srcPort))
|
|
||||||
if err != nil {
|
|
||||||
log.Debugln("[Process] find process %s: %v", metadata.String(), err)
|
|
||||||
} else {
|
|
||||||
log.Debugln("[Process] %s from process %s", metadata.String(), path)
|
|
||||||
metadata.Process = filepath.Base(path)
|
|
||||||
metadata.ProcessPath = path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +372,10 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
|
|||||||
configMux.RLock()
|
configMux.RLock()
|
||||||
defer configMux.RUnlock()
|
defer configMux.RUnlock()
|
||||||
|
|
||||||
var resolved bool
|
var (
|
||||||
|
resolved bool
|
||||||
|
processFound bool
|
||||||
|
)
|
||||||
|
|
||||||
if node := resolver.DefaultHosts.Search(metadata.Host); node != nil {
|
if node := resolver.DefaultHosts.Search(metadata.Host); node != nil {
|
||||||
metadata.DstIP = node.Data
|
metadata.DstIP = node.Data
|
||||||
@ -404,6 +394,22 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
|
|||||||
resolved = true
|
resolved = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !processFound && rule.ShouldFindProcess() && P.ShouldFindProcess(metadata) {
|
||||||
|
processFound = true
|
||||||
|
|
||||||
|
srcPort, err := strconv.ParseUint(metadata.SrcPort, 10, 16)
|
||||||
|
if err == nil {
|
||||||
|
path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(srcPort))
|
||||||
|
if err != nil {
|
||||||
|
log.Debugln("[Process] find process %s: %v", metadata.String(), err)
|
||||||
|
} else {
|
||||||
|
log.Debugln("[Process] %s from process %s", metadata.String(), path)
|
||||||
|
metadata.Process = filepath.Base(path)
|
||||||
|
metadata.ProcessPath = path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if rule.Match(metadata) {
|
if rule.Match(metadata) {
|
||||||
adapter, ok := proxies[rule.Adapter()]
|
adapter, ok := proxies[rule.Adapter()]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
Reference in New Issue
Block a user