feat: urltest can be select by user

This commit is contained in:
gVisor bot 2023-04-08 02:04:16 +08:00
parent f06e6c220d
commit f821549558

View file

@ -3,6 +3,7 @@ package outboundgroup
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"time" "time"
"github.com/Dreamacro/clash/adapter/outbound" "github.com/Dreamacro/clash/adapter/outbound"
@ -24,6 +25,8 @@ func urlTestWithTolerance(tolerance uint16) urlTestOption {
type URLTest struct { type URLTest struct {
*GroupBase *GroupBase
selected string
testUrl string
tolerance uint16 tolerance uint16
disableUDP bool disableUDP bool
fastNode C.Proxy fastNode C.Proxy
@ -34,6 +37,22 @@ func (u *URLTest) Now() string {
return u.fast(false).Name() return u.fast(false).Name()
} }
func (u *URLTest) Set(name string) error {
var p C.Proxy
for _, proxy := range u.GetProxies(false) {
if proxy.Name() == name {
p = proxy
break
}
}
if p == nil {
return errors.New("proxy not exist")
}
u.selected = name
u.fast(false)
return nil
}
// DialContext implements C.ProxyAdapter // DialContext implements C.ProxyAdapter
func (u *URLTest) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (c C.Conn, err error) { func (u *URLTest) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (c C.Conn, err error) {
proxy := u.fast(true) proxy := u.fast(true)
@ -74,16 +93,24 @@ func (u *URLTest) Unwrap(metadata *C.Metadata, touch bool) C.Proxy {
func (u *URLTest) fast(touch bool) C.Proxy { func (u *URLTest) fast(touch bool) C.Proxy {
elm, _, shared := u.fastSingle.Do(func() (C.Proxy, error) { elm, _, shared := u.fastSingle.Do(func() (C.Proxy, error) {
var s C.Proxy
proxies := u.GetProxies(touch) proxies := u.GetProxies(touch)
fast := proxies[0] fast := proxies[0]
if fast.Name() == u.selected {
s = fast
}
min := fast.LastDelay() min := fast.LastDelay()
fastNotExist := true fastNotExist := true
for _, proxy := range proxies[1:] { for _, proxy := range proxies[1:] {
if u.fastNode != nil && proxy.Name() == u.fastNode.Name() { if u.fastNode != nil && proxy.Name() == u.fastNode.Name() {
fastNotExist = false fastNotExist = false
} }
if proxy.Name() == u.selected {
s = proxy
}
if !proxy.Alive() { if !proxy.Alive() {
continue continue
} }
@ -94,12 +121,15 @@ func (u *URLTest) fast(touch bool) C.Proxy {
min = delay min = delay
} }
} }
// tolerance // tolerance
if u.fastNode == nil || fastNotExist || !u.fastNode.Alive() || u.fastNode.LastDelay() > fast.LastDelay()+u.tolerance { if u.fastNode == nil || fastNotExist || !u.fastNode.Alive() || u.fastNode.LastDelay() > fast.LastDelay()+u.tolerance {
u.fastNode = fast u.fastNode = fast
} }
if s != nil {
if s.Alive() && s.LastDelay() < fast.LastDelay()+u.tolerance {
u.fastNode = s
}
}
return u.fastNode, nil return u.fastNode, nil
}) })
if shared && touch { // a shared fastSingle.Do() may cause providers untouched, so we touch them again if shared && touch { // a shared fastSingle.Do() may cause providers untouched, so we touch them again
@ -114,7 +144,6 @@ func (u *URLTest) SupportUDP() bool {
if u.disableUDP { if u.disableUDP {
return false return false
} }
return u.fast(false).SupportUDP() return u.fast(false).SupportUDP()
} }
@ -161,6 +190,7 @@ func NewURLTest(option *GroupCommonOption, providers []provider.ProxyProvider, o
}), }),
fastSingle: singledo.NewSingle[C.Proxy](time.Second * 10), fastSingle: singledo.NewSingle[C.Proxy](time.Second * 10),
disableUDP: option.DisableUDP, disableUDP: option.DisableUDP,
testUrl: option.URL,
} }
for _, option := range options { for _, option := range options {