Merge remote-tracking branch 'clash/dev' into Alpha

# Conflicts:
#	.github/workflows/docker.yml
#	adapter/outboundgroup/fallback.go
#	adapter/outboundgroup/loadbalance.go
#	adapter/outboundgroup/relay.go
#	adapter/outboundgroup/selector.go
#	adapter/outboundgroup/urltest.go
#	config/config.go
#	go.mod
#	go.sum
#	main.go
#	test/go.mod
#	test/go.sum
This commit is contained in:
MetaCubeX 2022-03-17 01:41:51 +08:00
commit 609d69191a
70 changed files with 241 additions and 255 deletions

View file

@ -2,7 +2,7 @@ linters:
disable-all: true
enable:
- gofumpt
- megacheck
- staticcheck
- govet
- gci
@ -12,3 +12,5 @@ linters-settings:
- standard
- prefix(github.com/Dreamacro/clash)
- default
staticcheck:
go: '1.18'

View file

@ -41,10 +41,10 @@ all:linux-amd64\
linux-mips-hardfloat linux-mips-softfloat linux-mips64 linux-mips64le linux-mipsle-hardfloat linux-mipsle-softfloat# Most used
docker:
$(GOBUILD) -o $(BINDIR)/$(NAME)-$@
GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
darwin-amd64:
GOARCH=amd64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=amd64 GOOS=darwin GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
darwin-arm64:
GOARCH=arm64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
@ -53,7 +53,7 @@ linux-386:
GOARCH=386 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
linux-amd64:
GOARCH=amd64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=amd64 GOOS=linux GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
linux-amd64-AutoIptables:
GOARCH=amd64 GOOS=linux $(GOBUILDOP) -o $(BINDIR)/$(NAME)-$@
@ -98,7 +98,7 @@ freebsd-386:
GOARCH=386 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
freebsd-amd64:
GOARCH=amd64 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
GOARCH=amd64 GOOS=freebsd GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
freebsd-arm64:
GOARCH=arm64 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@
@ -107,7 +107,7 @@ windows-386:
GOARCH=386 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
windows-amd64:
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
GOARCH=amd64 GOOS=windows GOAMD64=v3 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
windows-arm64:
GOARCH=arm64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe

View file

@ -93,7 +93,7 @@ func (p *Proxy) MarshalJSON() ([]byte, error) {
return inner, err
}
mapping := map[string]interface{}{}
mapping := map[string]any{}
json.Unmarshal(inner, &mapping)
mapping["history"] = p.DelayHistory()
mapping["name"] = p.Name()

View file

@ -29,14 +29,14 @@ type ShadowSocks struct {
type ShadowSocksOption struct {
BasicOption
Name string `proxy:"name"`
Server string `proxy:"server"`
Port int `proxy:"port"`
Password string `proxy:"password"`
Cipher string `proxy:"cipher"`
UDP bool `proxy:"udp,omitempty"`
Plugin string `proxy:"plugin,omitempty"`
PluginOpts map[string]interface{} `proxy:"plugin-opts,omitempty"`
Name string `proxy:"name"`
Server string `proxy:"server"`
Port int `proxy:"port"`
Password string `proxy:"password"`
Cipher string `proxy:"cipher"`
UDP bool `proxy:"udp,omitempty"`
Plugin string `proxy:"plugin,omitempty"`
PluginOpts map[string]any `proxy:"plugin-opts,omitempty"`
}
type simpleObfsOption struct {

View file

@ -23,13 +23,13 @@ type Snell struct {
type SnellOption struct {
BasicOption
Name string `proxy:"name"`
Server string `proxy:"server"`
Port int `proxy:"port"`
Psk string `proxy:"psk"`
UDP bool `proxy:"udp,omitempty"`
Version int `proxy:"version,omitempty"`
ObfsOpts map[string]interface{} `proxy:"obfs-opts,omitempty"`
Name string `proxy:"name"`
Server string `proxy:"server"`
Port int `proxy:"port"`
Psk string `proxy:"psk"`
UDP bool `proxy:"udp,omitempty"`
Version int `proxy:"version,omitempty"`
ObfsOpts map[string]any `proxy:"obfs-opts,omitempty"`
}
type streamOption struct {

View file

@ -97,12 +97,11 @@ func (f *Fallback) SupportUDP() bool {
// MarshalJSON implements C.ProxyAdapter
func (f *Fallback) MarshalJSON() ([]byte, error) {
all := make([]string, 0)
var all []string
for _, proxy := range f.proxies(false) {
all = append(all, proxy.Name())
}
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"type": f.Type().String(),
"now": f.Now(),
"all": all,
@ -116,8 +115,8 @@ func (f *Fallback) Unwrap(metadata *C.Metadata) C.Proxy {
}
func (f *Fallback) proxies(touch bool) []C.Proxy {
elm, _, _ := f.single.Do(func() (interface{}, error) {
return getProvidersProxies(f.providers, touch, f.filter), nil
elm, _, _ := f.single.Do(func() (any, error) {
return getProvidersProxies(f.providers, touch), nil
})
return elm.([]C.Proxy)

View file

@ -30,7 +30,7 @@ type LoadBalance struct {
var errStrategy = errors.New("unsupported strategy")
func parseStrategy(config map[string]interface{}) string {
func parseStrategy(config map[string]any) string {
if elm, ok := config["strategy"]; ok {
if strategy, ok := elm.(string); ok {
return strategy
@ -141,7 +141,7 @@ func (lb *LoadBalance) Unwrap(metadata *C.Metadata) C.Proxy {
}
func (lb *LoadBalance) proxies(touch bool) []C.Proxy {
elm, _, _ := lb.single.Do(func() (interface{}, error) {
elm, _, _ := lb.single.Do(func() (any, error) {
return getProvidersProxies(lb.providers, touch, lb.filter), nil
})
@ -150,13 +150,11 @@ func (lb *LoadBalance) proxies(touch bool) []C.Proxy {
// MarshalJSON implements C.ProxyAdapter
func (lb *LoadBalance) MarshalJSON() ([]byte, error) {
all := make([]string, 0)
var all []string
for _, proxy := range lb.proxies(false) {
all = append(all, proxy.Name())
}
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"type": lb.Type().String(),
"all": all,
})

View file

@ -32,7 +32,7 @@ type GroupCommonOption struct {
Filter string `group:"filter,omitempty"`
}
func ParseProxyGroup(config map[string]interface{}, proxyMap map[string]C.Proxy, providersMap map[string]types.ProxyProvider) (C.ProxyAdapter, error) {
func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, providersMap map[string]types.ProxyProvider) (C.ProxyAdapter, error) {
decoder := structure.NewDecoder(structure.Option{TagName: "group", WeaklyTypedInput: true})
groupOption := &GroupCommonOption{

View file

@ -69,20 +69,18 @@ func (r *Relay) DialContext(ctx context.Context, metadata *C.Metadata, opts ...d
// MarshalJSON implements C.ProxyAdapter
func (r *Relay) MarshalJSON() ([]byte, error) {
all := make([]string, 0)
var all []string
for _, proxy := range r.rawProxies(false) {
all = append(all, proxy.Name())
}
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"type": r.Type().String(),
"all": all,
})
}
func (r *Relay) rawProxies(touch bool) []C.Proxy {
elm, _, _ := r.single.Do(func() (interface{}, error) {
elm, _, _ := r.single.Do(func() (any, error) {
return getProvidersProxies(r.providers, touch, r.filter), nil
})

View file

@ -50,13 +50,12 @@ func (s *Selector) SupportUDP() bool {
// MarshalJSON implements C.ProxyAdapter
func (s *Selector) MarshalJSON() ([]byte, error) {
all := make([]string, 0)
var all []string
for _, proxy := range getProvidersProxies(s.providers, false, s.filter) {
all = append(all, proxy.Name())
}
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"type": s.Type().String(),
"now": s.Now(),
"all": all,
@ -85,7 +84,7 @@ func (s *Selector) Unwrap(metadata *C.Metadata) C.Proxy {
}
func (s *Selector) selectedProxy(touch bool) C.Proxy {
elm, _, _ := s.single.Do(func() (interface{}, error) {
elm, _, _ := s.single.Do(func() (any, error) {
proxies := getProvidersProxies(s.providers, touch, s.filter)
for _, proxy := range proxies {
if proxy.Name() == s.selected {

View file

@ -49,7 +49,6 @@ func (u *URLTest) DialContext(ctx context.Context, metadata *C.Metadata, opts ..
} else {
u.onDialFailed()
}
return c, err
}
@ -63,7 +62,6 @@ func (u *URLTest) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
} else {
u.onDialFailed()
}
return pc, err
}
@ -73,7 +71,7 @@ func (u *URLTest) Unwrap(metadata *C.Metadata) C.Proxy {
}
func (u *URLTest) proxies(touch bool) []C.Proxy {
elm, _, _ := u.single.Do(func() (interface{}, error) {
elm, _, _ := u.single.Do(func() (any, error) {
return getProvidersProxies(u.providers, touch, u.filter), nil
})
@ -81,7 +79,7 @@ func (u *URLTest) proxies(touch bool) []C.Proxy {
}
func (u *URLTest) fast(touch bool) C.Proxy {
elm, _, _ := u.fastSingle.Do(func() (interface{}, error) {
elm, _, _ := u.fastSingle.Do(func() (any, error) {
proxies := u.proxies(touch)
fast := proxies[0]
min := fast.LastDelay()
@ -125,13 +123,11 @@ func (u *URLTest) SupportUDP() bool {
// MarshalJSON implements C.ProxyAdapter
func (u *URLTest) MarshalJSON() ([]byte, error) {
all := make([]string, 0)
var all []string
for _, proxy := range u.proxies(false) {
all = append(all, proxy.Name())
}
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"type": u.Type().String(),
"now": u.Now(),
"all": all,
@ -164,7 +160,7 @@ func (u *URLTest) onDialFailed() {
}
}
func parseURLTestOption(config map[string]interface{}) []urlTestOption {
func parseURLTestOption(config map[string]any) []urlTestOption {
opts := []urlTestOption{}
// tolerance

View file

@ -8,7 +8,7 @@ import (
C "github.com/Dreamacro/clash/constant"
)
func ParseProxy(mapping map[string]interface{}) (C.Proxy, error) {
func ParseProxy(mapping map[string]any) (C.Proxy, error) {
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
proxyType, existType := mapping["type"].(string)
if !existType {

View file

@ -16,7 +16,7 @@ var (
dirMode os.FileMode = 0o755
)
type parser = func([]byte) (interface{}, error)
type parser = func([]byte) (any, error)
type fetcher struct {
name string
@ -26,7 +26,7 @@ type fetcher struct {
done chan struct{}
hash [16]byte
parser parser
onUpdate func(interface{})
onUpdate func(any)
}
func (f *fetcher) Name() string {
@ -37,7 +37,7 @@ func (f *fetcher) VehicleType() types.VehicleType {
return f.vehicle.Type()
}
func (f *fetcher) Initial() (interface{}, error) {
func (f *fetcher) Initial() (any, error) {
var (
buf []byte
err error
@ -92,7 +92,7 @@ func (f *fetcher) Initial() (interface{}, error) {
return proxies, nil
}
func (f *fetcher) Update() (interface{}, bool, error) {
func (f *fetcher) Update() (any, bool, error) {
buf, err := f.vehicle.Read()
if err != nil {
return nil, false, err
@ -168,7 +168,7 @@ func safeWrite(path string, buf []byte) error {
return os.WriteFile(path, buf, fileMode)
}
func newFetcher(name string, interval time.Duration, vehicle types.Vehicle, parser parser, onUpdate func(interface{})) *fetcher {
func newFetcher(name string, interval time.Duration, vehicle types.Vehicle, parser parser, onUpdate func(any)) *fetcher {
var ticker *time.Ticker
if interval != 0 {
ticker = time.NewTicker(interval)

View file

@ -62,7 +62,7 @@ func (hc *HealthCheck) check() {
b, _ := batch.New(context.Background(), batch.WithConcurrencyNum(10))
for _, proxy := range hc.proxies {
p := proxy
b.Go(p.Name(), func() (interface{}, error) {
b.Go(p.Name(), func() (any, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultURLTestTimeout)
defer cancel()
p.URLTest(ctx, hc.url)

View file

@ -28,7 +28,7 @@ type proxyProviderSchema struct {
HealthCheck healthCheckSchema `provider:"health-check,omitempty"`
}
func ParseProxyProvider(name string, mapping map[string]interface{}) (types.ProxyProvider, error) {
func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvider, error) {
decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true})
schema := &proxyProviderSchema{

View file

@ -20,7 +20,7 @@ const (
)
type ProxySchema struct {
Proxies []map[string]interface{} `yaml:"proxies"`
Proxies []map[string]any `yaml:"proxies"`
}
// for auto gc
@ -35,7 +35,7 @@ type proxySetProvider struct {
}
func (pp *proxySetProvider) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"name": pp.Name(),
"type": pp.Type().String(),
"vehicleType": pp.VehicleType().String(),
@ -112,12 +112,12 @@ func NewProxySetProvider(name string, interval time.Duration, filter string, veh
healthCheck: hc,
}
onUpdate := func(elm interface{}) {
onUpdate := func(elm any) {
ret := elm.([]C.Proxy)
pd.setProxies(ret)
}
proxiesParseAndFilter := func(buf []byte) (interface{}, error) {
proxiesParseAndFilter := func(buf []byte) (any, error) {
schema := &ProxySchema{}
if err := yaml.Unmarshal(buf, schema); err != nil {
@ -172,7 +172,7 @@ type compatibleProvider struct {
}
func (cp *compatibleProvider) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"name": cp.Name(),
"type": cp.Type().String(),
"vehicleType": cp.VehicleType().String(),

View file

@ -8,7 +8,7 @@ import (
type Option = func(b *Batch)
type Result struct {
Value interface{}
Value any
Err error
}
@ -38,7 +38,7 @@ type Batch struct {
cancel func()
}
func (b *Batch) Go(key string, fn func() (interface{}, error)) {
func (b *Batch) Go(key string, fn func() (any, error)) {
b.wg.Add(1)
go func() {
defer b.wg.Done()

View file

@ -14,11 +14,11 @@ func TestBatch(t *testing.T) {
b, _ := New(context.Background())
now := time.Now()
b.Go("foo", func() (interface{}, error) {
b.Go("foo", func() (any, error) {
time.Sleep(time.Millisecond * 100)
return "foo", nil
})
b.Go("bar", func() (interface{}, error) {
b.Go("bar", func() (any, error) {
time.Sleep(time.Millisecond * 150)
return "bar", nil
})
@ -45,7 +45,7 @@ func TestBatchWithConcurrencyNum(t *testing.T) {
now := time.Now()
for i := 0; i < 7; i++ {
idx := i
b.Go(strconv.Itoa(idx), func() (interface{}, error) {
b.Go(strconv.Itoa(idx), func() (any, error) {
time.Sleep(time.Millisecond * 100)
return strconv.Itoa(idx), nil
})
@ -64,12 +64,12 @@ func TestBatchWithConcurrencyNum(t *testing.T) {
func TestBatchContext(t *testing.T) {
b, ctx := New(context.Background())
b.Go("error", func() (interface{}, error) {
b.Go("error", func() (any, error) {
time.Sleep(time.Millisecond * 100)
return nil, errors.New("test error")
})
b.Go("ctx", func() (interface{}, error) {
b.Go("ctx", func() (any, error) {
<-ctx.Done()
return nil, ctx.Err()
})

10
common/cache/cache.go vendored
View file

@ -18,11 +18,11 @@ type cache struct {
type element struct {
Expired time.Time
Payload interface{}
Payload any
}
// Put element in Cache with its ttl
func (c *cache) Put(key interface{}, payload interface{}, ttl time.Duration) {
func (c *cache) Put(key any, payload any, ttl time.Duration) {
c.mapping.Store(key, &element{
Payload: payload,
Expired: time.Now().Add(ttl),
@ -30,7 +30,7 @@ func (c *cache) Put(key interface{}, payload interface{}, ttl time.Duration) {
}
// Get element in Cache, and drop when it expired
func (c *cache) Get(key interface{}) interface{} {
func (c *cache) Get(key any) any {
item, exist := c.mapping.Load(key)
if !exist {
return nil
@ -45,7 +45,7 @@ func (c *cache) Get(key interface{}) interface{} {
}
// GetWithExpire element in Cache with Expire Time
func (c *cache) GetWithExpire(key interface{}) (payload interface{}, expired time.Time) {
func (c *cache) GetWithExpire(key any) (payload any, expired time.Time) {
item, exist := c.mapping.Load(key)
if !exist {
return
@ -60,7 +60,7 @@ func (c *cache) GetWithExpire(key interface{}) (payload interface{}, expired tim
}
func (c *cache) cleanup() {
c.mapping.Range(func(k, v interface{}) bool {
c.mapping.Range(func(k, v any) bool {
key := k.(string)
elm := v.(*element)
if time.Since(elm.Expired) > 0 {

View file

@ -12,7 +12,7 @@ import (
type Option func(*LruCache)
// EvictCallback is used to get a callback when a cache entry is evicted
type EvictCallback = func(key interface{}, value interface{})
type EvictCallback = func(key any, value any)
// WithEvict set the evict callback
func WithEvict(cb EvictCallback) Option {
@ -57,7 +57,7 @@ type LruCache struct {
maxAge int64
maxSize int
mu sync.Mutex
cache map[interface{}]*list.Element
cache map[any]*list.Element
lru *list.List // Front is least-recent
updateAgeOnGet bool
staleReturn bool
@ -68,7 +68,7 @@ type LruCache struct {
func NewLRUCache(options ...Option) *LruCache {
lc := &LruCache{
lru: list.New(),
cache: make(map[interface{}]*list.Element),
cache: make(map[any]*list.Element),
}
for _, option := range options {
@ -78,9 +78,9 @@ func NewLRUCache(options ...Option) *LruCache {
return lc
}
// Get returns the interface{} representation of a cached response and a bool
// Get returns the any representation of a cached response and a bool
// set to true if the key was found.
func (c *LruCache) Get(key interface{}) (interface{}, bool) {
func (c *LruCache) Get(key any) (any, bool) {
entry := c.get(key)
if entry == nil {
return nil, false
@ -90,11 +90,11 @@ func (c *LruCache) Get(key interface{}) (interface{}, bool) {
return value, true
}
// GetWithExpire returns the interface{} representation of a cached response,
// GetWithExpire returns the any representation of a cached response,
// a time.Time Give expected expires,
// and a bool set to true if the key was found.
// This method will NOT check the maxAge of element and will NOT update the expires.
func (c *LruCache) GetWithExpire(key interface{}) (interface{}, time.Time, bool) {
func (c *LruCache) GetWithExpire(key any) (any, time.Time, bool) {
entry := c.get(key)
if entry == nil {
return nil, time.Time{}, false
@ -104,7 +104,7 @@ func (c *LruCache) GetWithExpire(key interface{}) (interface{}, time.Time, bool)
}
// Exist returns if key exist in cache but not put item to the head of linked list
func (c *LruCache) Exist(key interface{}) bool {
func (c *LruCache) Exist(key any) bool {
c.mu.Lock()
defer c.mu.Unlock()
@ -112,8 +112,8 @@ func (c *LruCache) Exist(key interface{}) bool {
return ok
}
// Set stores the interface{} representation of a response for a given key.
func (c *LruCache) Set(key interface{}, value interface{}) {
// Set stores the any representation of a response for a given key.
func (c *LruCache) Set(key any, value any) {
expires := int64(0)
if c.maxAge > 0 {
expires = time.Now().Unix() + c.maxAge
@ -121,9 +121,9 @@ func (c *LruCache) Set(key interface{}, value interface{}) {
c.SetWithExpire(key, value, time.Unix(expires, 0))
}
// SetWithExpire stores the interface{} representation of a response for a given key and given expires.
// SetWithExpire stores the any representation of a response for a given key and given expires.
// The expires time will round to second.
func (c *LruCache) SetWithExpire(key interface{}, value interface{}, expires time.Time) {
func (c *LruCache) SetWithExpire(key any, value any, expires time.Time) {
c.mu.Lock()
defer c.mu.Unlock()
@ -155,7 +155,7 @@ func (c *LruCache) CloneTo(n *LruCache) {
defer n.mu.Unlock()
n.lru = list.New()
n.cache = make(map[interface{}]*list.Element)
n.cache = make(map[any]*list.Element)
for e := c.lru.Front(); e != nil; e = e.Next() {
elm := e.Value.(*entry)
@ -163,7 +163,7 @@ func (c *LruCache) CloneTo(n *LruCache) {
}
}
func (c *LruCache) get(key interface{}) *entry {
func (c *LruCache) get(key any) *entry {
c.mu.Lock()
defer c.mu.Unlock()
@ -188,7 +188,7 @@ func (c *LruCache) get(key interface{}) *entry {
}
// Delete removes the value associated with a key.
func (c *LruCache) Delete(key interface{}) {
func (c *LruCache) Delete(key any) {
c.mu.Lock()
if le, ok := c.cache[key]; ok {
@ -217,7 +217,7 @@ func (c *LruCache) deleteElement(le *list.Element) {
}
type entry struct {
key interface{}
value interface{}
key any
value any
expires int64
}

View file

@ -126,7 +126,7 @@ func TestExist(t *testing.T) {
func TestEvict(t *testing.T) {
temp := 0
evict := func(key interface{}, value interface{}) {
evict := func(key any, value any) {
temp = key.(int) + value.(int)
}

View file

@ -1,3 +1,3 @@
package observable
type Iterable <-chan interface{}
type Iterable <-chan any

View file

@ -9,8 +9,8 @@ import (
"go.uber.org/atomic"
)
func iterator(item []interface{}) chan interface{} {
ch := make(chan interface{})
func iterator(item []any) chan any {
ch := make(chan any)
go func() {
time.Sleep(100 * time.Millisecond)
for _, elm := range item {
@ -22,7 +22,7 @@ func iterator(item []interface{}) chan interface{} {
}
func TestObservable(t *testing.T) {
iter := iterator([]interface{}{1, 2, 3, 4, 5})
iter := iterator([]any{1, 2, 3, 4, 5})
src := NewObservable(iter)
data, err := src.Subscribe()
assert.Nil(t, err)
@ -34,7 +34,7 @@ func TestObservable(t *testing.T) {
}
func TestObservable_MultiSubscribe(t *testing.T) {
iter := iterator([]interface{}{1, 2, 3, 4, 5})
iter := iterator([]any{1, 2, 3, 4, 5})
src := NewObservable(iter)
ch1, _ := src.Subscribe()
ch2, _ := src.Subscribe()
@ -42,7 +42,7 @@ func TestObservable_MultiSubscribe(t *testing.T) {
var wg sync.WaitGroup
wg.Add(2)
waitCh := func(ch <-chan interface{}) {
waitCh := func(ch <-chan any) {
for range ch {
count.Inc()
}
@ -55,7 +55,7 @@ func TestObservable_MultiSubscribe(t *testing.T) {
}
func TestObservable_UnSubscribe(t *testing.T) {
iter := iterator([]interface{}{1, 2, 3, 4, 5})
iter := iterator([]any{1, 2, 3, 4, 5})
src := NewObservable(iter)
data, err := src.Subscribe()
assert.Nil(t, err)
@ -65,7 +65,7 @@ func TestObservable_UnSubscribe(t *testing.T) {
}
func TestObservable_SubscribeClosedSource(t *testing.T) {
iter := iterator([]interface{}{1})
iter := iterator([]any{1})
src := NewObservable(iter)
data, _ := src.Subscribe()
<-data
@ -75,14 +75,14 @@ func TestObservable_SubscribeClosedSource(t *testing.T) {
}
func TestObservable_UnSubscribeWithNotExistSubscription(t *testing.T) {
sub := Subscription(make(chan interface{}))
iter := iterator([]interface{}{1})
sub := Subscription(make(chan any))
iter := iterator([]any{1})
src := NewObservable(iter)
src.UnSubscribe(sub)
}
func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
iter := iterator([]interface{}{1, 2, 3, 4, 5})
iter := iterator([]any{1, 2, 3, 4, 5})
src := NewObservable(iter)
max := 100
@ -94,7 +94,7 @@ func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
var wg sync.WaitGroup
wg.Add(max)
waitCh := func(ch <-chan interface{}) {
waitCh := func(ch <-chan any) {
for range ch {
}
wg.Done()
@ -115,7 +115,7 @@ func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
}
func Benchmark_Observable_1000(b *testing.B) {
ch := make(chan interface{})
ch := make(chan any)
o := NewObservable(ch)
num := 1000

View file

@ -4,14 +4,14 @@ import (
"sync"
)
type Subscription <-chan interface{}
type Subscription <-chan any
type Subscriber struct {
buffer chan interface{}
buffer chan any
once sync.Once
}
func (s *Subscriber) Emit(item interface{}) {
func (s *Subscriber) Emit(item any) {
s.buffer <- item
}
@ -27,7 +27,7 @@ func (s *Subscriber) Close() {
func newSubscriber() *Subscriber {
sub := &Subscriber{
buffer: make(chan interface{}, 200),
buffer: make(chan any, 200),
}
return sub
}

View file

@ -17,7 +17,7 @@ type Picker struct {
once sync.Once
errOnce sync.Once
result interface{}
result any
err error
}
@ -43,7 +43,7 @@ func WithTimeout(ctx context.Context, timeout time.Duration) (*Picker, context.C
// Wait blocks until all function calls from the Go method have returned,
// then returns the first nil error result (if any) from them.
func (p *Picker) Wait() interface{} {
func (p *Picker) Wait() any {
p.wg.Wait()
if p.cancel != nil {
p.cancel()
@ -58,7 +58,7 @@ func (p *Picker) Error() error {
// Go calls the given function in a new goroutine.
// The first call to return a nil error cancels the group; its result will be returned by Wait.
func (p *Picker) Go(f func() (interface{}, error)) {
func (p *Picker) Go(f func() (any, error)) {
p.wg.Add(1)
go func() {

View file

@ -8,8 +8,8 @@ import (
"github.com/stretchr/testify/assert"
)
func sleepAndSend(ctx context.Context, delay int, input interface{}) func() (interface{}, error) {
return func() (interface{}, error) {
func sleepAndSend(ctx context.Context, delay int, input any) func() (any, error) {
return func() (any, error) {
timer := time.NewTimer(time.Millisecond * time.Duration(delay))
select {
case <-timer.C:

View file

@ -23,7 +23,7 @@ func NewAllocator() *Allocator {
alloc.buffers = make([]sync.Pool, 17) // 1B -> 64K
for k := range alloc.buffers {
i := k
alloc.buffers[k].New = func() interface{} {
alloc.buffers[k].New = func() any {
return make([]byte, 1<<uint32(i))
}
}

View file

@ -5,7 +5,7 @@ import (
"sync"
)
var bufferPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
var bufferPool = sync.Pool{New: func() any { return &bytes.Buffer{} }}
func GetBuffer() *bytes.Buffer {
return bufferPool.Get().(*bytes.Buffer)

View file

@ -6,12 +6,12 @@ import (
// Queue is a simple concurrent safe queue
type Queue struct {
items []interface{}
items []any
lock sync.RWMutex
}
// Put add the item to the queue.
func (q *Queue) Put(items ...interface{}) {
func (q *Queue) Put(items ...any) {
if len(items) == 0 {
return
}
@ -22,7 +22,7 @@ func (q *Queue) Put(items ...interface{}) {
}
// Pop returns the head of items.
func (q *Queue) Pop() interface{} {
func (q *Queue) Pop() any {
if len(q.items) == 0 {
return nil
}
@ -35,7 +35,7 @@ func (q *Queue) Pop() interface{} {
}
// Last returns the last of item.
func (q *Queue) Last() interface{} {
func (q *Queue) Last() any {
if len(q.items) == 0 {
return nil
}
@ -47,8 +47,8 @@ func (q *Queue) Last() interface{} {
}
// Copy get the copy of queue.
func (q *Queue) Copy() []interface{} {
items := []interface{}{}
func (q *Queue) Copy() []any {
items := []any{}
q.lock.RLock()
items = append(items, q.items...)
q.lock.RUnlock()
@ -66,6 +66,6 @@ func (q *Queue) Len() int64 {
// New is a constructor for a new concurrent safe queue.
func New(hint int64) *Queue {
return &Queue{
items: make([]interface{}, 0, hint),
items: make([]any, 0, hint),
}
}

View file

@ -7,7 +7,7 @@ import (
type call struct {
wg sync.WaitGroup
val interface{}
val any
err error
}
@ -20,13 +20,13 @@ type Single struct {
}
type Result struct {
Val interface{}
Val any
Err error
}
// Do single.Do likes sync.singleFlight
//lint:ignore ST1008 it likes sync.singleFlight
func (s *Single) Do(fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
func (s *Single) Do(fn func() (any, error)) (v any, err error, shared bool) {
s.mux.Lock()
now := time.Now()
if now.Before(s.last.Add(s.wait)) {

View file

@ -13,7 +13,7 @@ func TestBasic(t *testing.T) {
single := NewSingle(time.Millisecond * 30)
foo := 0
shardCount := atomic.NewInt32(0)
call := func() (interface{}, error) {
call := func() (any, error) {
foo++
time.Sleep(time.Millisecond * 5)
return nil, nil
@ -40,7 +40,7 @@ func TestBasic(t *testing.T) {
func TestTimer(t *testing.T) {
single := NewSingle(time.Millisecond * 30)
foo := 0
call := func() (interface{}, error) {
call := func() (any, error) {
foo++
return nil, nil
}
@ -56,7 +56,7 @@ func TestTimer(t *testing.T) {
func TestReset(t *testing.T) {
single := NewSingle(time.Millisecond * 30)
foo := 0
call := func() (interface{}, error) {
call := func() (any, error) {
foo++
return nil, nil
}

View file

@ -1,5 +1,4 @@
//go:build !linux
// +build !linux
package sockopt

View file

@ -28,8 +28,8 @@ func NewDecoder(option Option) *Decoder {
return &Decoder{option: &option}
}
// Decode transform a map[string]interface{} to a struct
func (d *Decoder) Decode(src map[string]interface{}, dst interface{}) error {
// Decode transform a map[string]any to a struct
func (d *Decoder) Decode(src map[string]any, dst any) error {
if reflect.TypeOf(dst).Kind() != reflect.Ptr {
return fmt.Errorf("Decode must recive a ptr struct")
}
@ -45,12 +45,8 @@ func (d *Decoder) Decode(src map[string]interface{}, dst interface{}) error {
}
tag := field.Tag.Get(d.option.TagName)
str := strings.SplitN(tag, ",", 2)
key := str[0]
omitempty := false
if len(str) > 1 {
omitempty = str[1] == "omitempty"
}
key, omitKey, found := strings.Cut(tag, ",")
omitempty := found && omitKey == "omitempty"
value, ok := src[key]
if !ok || value == nil {
@ -68,7 +64,7 @@ func (d *Decoder) Decode(src map[string]interface{}, dst interface{}) error {
return nil
}
func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error {
func (d *Decoder) decode(name string, data any, val reflect.Value) error {
switch val.Kind() {
case reflect.Int:
return d.decodeInt(name, data, val)
@ -89,7 +85,7 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
}
}
func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) (err error) {
func (d *Decoder) decodeInt(name string, data any, val reflect.Value) (err error) {
dataVal := reflect.ValueOf(data)
kind := dataVal.Kind()
switch {
@ -112,7 +108,7 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) (e
return err
}
func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) (err error) {
func (d *Decoder) decodeString(name string, data any, val reflect.Value) (err error) {
dataVal := reflect.ValueOf(data)
kind := dataVal.Kind()
switch {
@ -129,7 +125,7 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
return err
}
func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) (err error) {
func (d *Decoder) decodeBool(name string, data any, val reflect.Value) (err error) {
dataVal := reflect.ValueOf(data)
kind := dataVal.Kind()
switch {
@ -146,7 +142,7 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) (
return err
}
func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
func (d *Decoder) decodeSlice(name string, data any, val reflect.Value) error {
dataVal := reflect.Indirect(reflect.ValueOf(data))
valType := val.Type()
valElemType := valType.Elem()
@ -173,7 +169,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
return nil
}
func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
func (d *Decoder) decodeMap(name string, data any, val reflect.Value) error {
valType := val.Type()
valKeyType := valType.Key()
valElemType := valType.Elem()
@ -245,7 +241,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
return nil
}
func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
func (d *Decoder) decodeStruct(name string, data any, val reflect.Value) error {
dataVal := reflect.Indirect(reflect.ValueOf(data))
// If the type of the value to write to and the data match directly,
@ -273,7 +269,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
}
dataValKeys := make(map[reflect.Value]struct{})
dataValKeysUnused := make(map[interface{}]struct{})
dataValKeysUnused := make(map[any]struct{})
for _, dataValKey := range dataVal.MapKeys() {
dataValKeys[dataValKey] = struct{}{}
dataValKeysUnused[dataValKey.Interface()] = struct{}{}
@ -398,7 +394,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
return nil
}
func (d *Decoder) setInterface(name string, data interface{}, val reflect.Value) (err error) {
func (d *Decoder) setInterface(name string, data any, val reflect.Value) (err error) {
dataVal := reflect.ValueOf(data)
val.Set(dataVal)
return nil

View file

@ -27,7 +27,7 @@ type BazOptional struct {
}
func TestStructure_Basic(t *testing.T) {
rawMap := map[string]interface{}{
rawMap := map[string]any{
"foo": 1,
"bar": "test",
"extra": false,
@ -45,7 +45,7 @@ func TestStructure_Basic(t *testing.T) {
}
func TestStructure_Slice(t *testing.T) {
rawMap := map[string]interface{}{
rawMap := map[string]any{
"foo": 1,
"bar": []string{"one", "two"},
}
@ -62,7 +62,7 @@ func TestStructure_Slice(t *testing.T) {
}
func TestStructure_Optional(t *testing.T) {
rawMap := map[string]interface{}{
rawMap := map[string]any{
"foo": 1,
}
@ -77,7 +77,7 @@ func TestStructure_Optional(t *testing.T) {
}
func TestStructure_MissingKey(t *testing.T) {
rawMap := map[string]interface{}{
rawMap := map[string]any{
"foo": 1,
}
@ -87,14 +87,14 @@ func TestStructure_MissingKey(t *testing.T) {
}
func TestStructure_ParamError(t *testing.T) {
rawMap := map[string]interface{}{}
rawMap := map[string]any{}
s := Baz{}
err := decoder.Decode(rawMap, s)
assert.NotNilf(t, err, "should throw error: %#v", s)
}
func TestStructure_SliceTypeError(t *testing.T) {
rawMap := map[string]interface{}{
rawMap := map[string]any{
"foo": 1,
"bar": []int{1, 2},
}
@ -105,7 +105,7 @@ func TestStructure_SliceTypeError(t *testing.T) {
}
func TestStructure_WeakType(t *testing.T) {
rawMap := map[string]interface{}{
rawMap := map[string]any{
"foo": "1",
"bar": []int{1},
}
@ -122,7 +122,7 @@ func TestStructure_WeakType(t *testing.T) {
}
func TestStructure_Nest(t *testing.T) {
rawMap := map[string]interface{}{
rawMap := map[string]any{
"foo": 1,
}

View file

@ -36,7 +36,7 @@ func NewAuthenticator(users []AuthUser) Authenticator {
au.storage.Store(user.User, user.Pass)
}
usernames := make([]string, 0, len(users))
au.storage.Range(func(key, value interface{}) bool {
au.storage.Range(func(key, value any) bool {
usernames = append(usernames, key.(string))
return true
})

View file

@ -1,5 +1,4 @@
//go:build !linux && !darwin
// +build !linux,!darwin
package dialer

View file

@ -1,5 +1,4 @@
//go:build linux
// +build linux
package dialer

View file

@ -1,5 +1,4 @@
//go:build !linux
// +build !linux
package dialer

View file

@ -1,5 +1,4 @@
//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package dialer

View file

@ -1,5 +1,4 @@
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package dialer

View file

@ -23,7 +23,7 @@ var (
var interfaces = singledo.NewSingle(time.Second * 20)
func ResolveInterface(name string) (*Interface, error) {
value, err, _ := interfaces.Do(func() (interface{}, error) {
value, err, _ := interfaces.Do(func() (any, error) {
ifaces, err := net.Interfaces()
if err != nil {
return nil, err

View file

@ -6,17 +6,17 @@ import (
"time"
)
type Factory = func(context.Context) (interface{}, error)
type Factory = func(context.Context) (any, error)
type entry struct {
elm interface{}
elm any
time time.Time
}
type Option func(*pool)
// WithEvict set the evict callback
func WithEvict(cb func(interface{})) Option {
func WithEvict(cb func(any)) Option {
return func(p *pool) {
p.evict = cb
}
@ -32,7 +32,7 @@ func WithAge(maxAge int64) Option {
// WithSize defined max size of Pool
func WithSize(maxSize int) Option {
return func(p *pool) {
p.ch = make(chan interface{}, maxSize)
p.ch = make(chan any, maxSize)
}
}
@ -42,13 +42,13 @@ type Pool struct {
}
type pool struct {
ch chan interface{}
ch chan any
factory Factory
evict func(interface{})
evict func(any)
maxAge int64
}
func (p *pool) GetContext(ctx context.Context) (interface{}, error) {
func (p *pool) GetContext(ctx context.Context) (any, error) {
now := time.Now()
for {
select {
@ -68,11 +68,11 @@ func (p *pool) GetContext(ctx context.Context) (interface{}, error) {
}
}
func (p *pool) Get() (interface{}, error) {
func (p *pool) Get() (any, error) {
return p.GetContext(context.Background())
}
func (p *pool) Put(item interface{}) {
func (p *pool) Put(item any) {
e := &entry{
elm: item,
time: time.Now(),
@ -100,7 +100,7 @@ func recycle(p *Pool) {
func New(factory Factory, options ...Option) *Pool {
p := &pool{
ch: make(chan interface{}, 10),
ch: make(chan any, 10),
factory: factory,
}

View file

@ -10,7 +10,7 @@ import (
func lg() Factory {
initial := -1
return func(context.Context) (interface{}, error) {
return func(context.Context) (any, error) {
initial++
return initial, nil
}
@ -34,7 +34,7 @@ func TestPool_MaxSize(t *testing.T) {
size := 5
pool := New(g, WithSize(size))
items := []interface{}{}
items := []any{}
for i := 0; i < size; i++ {
item, _ := pool.Get()

View file

@ -1,8 +1,4 @@
//go:build !darwin && !linux && !windows && (!freebsd || !amd64)
// +build !darwin
// +build !linux
// +build !windows
// +build !freebsd !amd64
package process

View file

@ -51,7 +51,7 @@ func ValidAndSplitDomain(domain string) ([]string, bool) {
// 3. subdomain.*.example.com
// 4. .example.com
// 5. +.example.com
func (t *DomainTrie) Insert(domain string, data interface{}) error {
func (t *DomainTrie) Insert(domain string, data any) error {
parts, valid := ValidAndSplitDomain(domain)
if !valid {
return ErrInvalidDomain
@ -68,7 +68,7 @@ func (t *DomainTrie) Insert(domain string, data interface{}) error {
return nil
}
func (t *DomainTrie) insert(parts []string, data interface{}) {
func (t *DomainTrie) insert(parts []string, data any) {
node := t.root
// reverse storage domain part to save space
for i := len(parts) - 1; i >= 0; i-- {

View file

@ -3,7 +3,7 @@ package trie
// Node is the trie's node
type Node struct {
children map[string]*Node
Data interface{}
Data any
}
func (n *Node) getChild(s string) *Node {
@ -18,7 +18,7 @@ func (n *Node) addChild(s string, child *Node) {
n.children[s] = child
}
func newNode(data interface{}) *Node {
func newNode(data any) *Node {
return &Node{
Data: data,
children: map[string]*Node{},

View file

@ -186,8 +186,8 @@ type RawConfig struct {
Tun Tun `yaml:"tun"`
Experimental Experimental `yaml:"experimental"`
Profile Profile `yaml:"profile"`
Proxy []map[string]interface{} `yaml:"proxies"`
ProxyGroup []map[string]interface{} `yaml:"proxy-groups"`
Proxy []map[string]any `yaml:"proxies"`
ProxyGroup []map[string]any
Rule []string `yaml:"rules"`
Script Script `yaml:"script"`
}
@ -216,8 +216,8 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
LogLevel: log.INFO,
Hosts: map[string]string{},
Rule: []string{},
Proxy: []map[string]interface{}{},
ProxyGroup: []map[string]interface{}{},
Proxy: []map[string]any{},
ProxyGroup: []map[string]any{},
Tun: Tun{
Enable: false,
Stack: "gvisor",
@ -432,7 +432,19 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
proxies[groupName] = adapter.NewProxy(group)
}
var ps []C.Proxy
// initial compatible provider
for _, pd := range providersMap {
if pd.VehicleType() != providerTypes.Compatible {
continue
}
log.Infoln("Start initial compatible provider %s", pd.Name())
if err := pd.Initial(); err != nil {
return nil, nil, err
}
}
ps := []C.Proxy{}
for _, v := range proxyList {
ps = append(ps, proxies[v])
}
@ -597,7 +609,7 @@ func parseHosts(cfg *RawConfig) (*trie.DomainTrie, error) {
if ip == nil {
return nil, fmt.Errorf("%s is not a valid IP", ipStr)
}
_ = tree.Insert(domain, ip)
tree.Insert(domain, ip)
}
}
@ -622,7 +634,7 @@ func hostWithDefaultPort(host string, defPort string) (string, error) {
}
func parseNameServer(servers []string) ([]dns.NameServer, error) {
var nameservers []dns.NameServer
nameservers := []dns.NameServer{}
for idx, server := range servers {
// parse without scheme .e.g 8.8.8.8:53
@ -693,7 +705,7 @@ func parseNameServerPolicy(nsPolicy map[string]string) (map[string]dns.NameServe
}
func parseFallbackIPCIDR(ips []string) ([]*net.IPNet, error) {
var ipNets []*net.IPNet
ipNets := []*net.IPNet{}
for idx, ip := range ips {
_, ipnet, err := net.ParseCIDR(ip)
@ -795,7 +807,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
if len(cfg.FakeIPFilter) != 0 {
host = trie.New()
for _, domain := range cfg.FakeIPFilter {
_ = host.Insert(domain, true)
host.Insert(domain, true)
}
}
@ -846,11 +858,10 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
}
func parseAuthentication(rawRecords []string) []auth.AuthUser {
users := make([]auth.AuthUser, 0)
users := []auth.AuthUser{}
for _, line := range rawRecords {
userData := strings.SplitN(line, ":", 2)
if len(userData) == 2 {
users = append(users, auth.AuthUser{User: userData[0], Pass: userData[1]})
if user, pass, found := strings.Cut(line, ":"); found {
users = append(users, auth.AuthUser{User: user, Pass: pass})
}
}
return users

View file

@ -18,13 +18,13 @@ func trimArr(arr []string) (r []string) {
// Check if ProxyGroups form DAG(Directed Acyclic Graph), and sort all ProxyGroups by dependency order.
// Meanwhile, record the original index in the config file.
// If loop is detected, return an error with location of loop.
func proxyGroupsDagSort(groupsConfig []map[string]interface{}) error {
func proxyGroupsDagSort(groupsConfig []map[string]any) error {
type graphNode struct {
indegree int
// topological order
topo int
// the original data in `groupsConfig`
data map[string]interface{}
data map[string]any
// `outdegree` and `from` are used in loop locating
outdegree int
option *outboundgroup.GroupCommonOption

View file

@ -21,7 +21,7 @@ const (
type DNSMode int
// UnmarshalYAML unserialize EnhancedMode with yaml
func (e *DNSMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
func (e *DNSMode) UnmarshalYAML(unmarshal func(any) error) error {
var tp string
if err := unmarshal(&tp); err != nil {
return err
@ -35,7 +35,7 @@ func (e *DNSMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
// MarshalYAML serialize EnhancedMode with yaml
func (e DNSMode) MarshalYAML() (interface{}, error) {
func (e DNSMode) MarshalYAML() (any, error) {
return e.String(), nil
}

View file

@ -118,7 +118,7 @@ func (r *Resolver) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, e
func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
q := m.Question[0]
ret, err, shared := r.group.Do(q.String(), func() (result interface{}, err error) {
ret, err, shared := r.group.Do(q.String(), func() (result any, err error) {
defer func() {
if err != nil {
return
@ -154,7 +154,7 @@ func (r *Resolver) batchExchange(ctx context.Context, clients []dnsClient, m *D.
fast, ctx := picker.WithTimeout(ctx, resolver.DefaultDNSTimeout)
for _, client := range clients {
r := client
fast.Go(func() (interface{}, error) {
fast.Go(func() (any, error) {
m, err := r.ExchangeContext(ctx, m)
if err != nil {
return nil, err

1
go.mod
View file

@ -53,5 +53,4 @@ require (
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)

View file

@ -117,10 +117,10 @@ func authentication(next http.Handler) http.Handler {
}
header := r.Header.Get("Authorization")
text := strings.SplitN(header, " ", 2)
bearer, token, found := strings.Cut(header, " ")
hasInvalidHeader := text[0] != "Bearer"
hasInvalidSecret := len(text) != 2 || text[1] != serverSecret
hasInvalidHeader := bearer != "Bearer"
hasInvalidSecret := !found || token != serverSecret
if hasInvalidHeader || hasInvalidSecret {
render.Status(r, http.StatusUnauthorized)
render.JSON(w, r, ErrUnauthorized)

View file

@ -108,7 +108,7 @@ func authenticate(request *http.Request, cache *cache.Cache) *http.Response {
return resp
}
var authed interface{}
var authed any
if authed = cache.Get(credential); authed == nil {
user, pass, err := decodeBasicProxyAuthorization(credential)
authed = err == nil && authenticator.Verify(user, pass)

View file

@ -65,10 +65,10 @@ func decodeBasicProxyAuthorization(credential string) (string, string, error) {
return "", "", err
}
login := strings.Split(string(plain), ":")
if len(login) != 2 {
user, pass, found := strings.Cut(string(plain), ":")
if !found {
return "", "", errors.New("invalid login")
}
return login[0], login[1], nil
return user, pass, nil
}

View file

@ -1,5 +1,4 @@
//go:build linux && !386
// +build linux,!386
package redir

View file

@ -1,5 +1,4 @@
//go:build !darwin && !linux && !freebsd
// +build !darwin,!linux,!freebsd
package redir

View file

@ -1,5 +1,4 @@
//go:build linux
// +build linux
package tproxy

View file

@ -1,5 +1,4 @@
//go:build !linux
// +build !linux
package tproxy

View file

@ -1,5 +1,4 @@
//go:build linux
// +build linux
package tproxy

View file

@ -1,5 +1,4 @@
//go:build !linux
// +build !linux
package tproxy

View file

@ -25,7 +25,7 @@ const (
type LogLevel int
// UnmarshalYAML unserialize LogLevel with yaml
func (l *LogLevel) UnmarshalYAML(unmarshal func(interface{}) error) error {
func (l *LogLevel) UnmarshalYAML(unmarshal func(any) error) error {
var tp string
unmarshal(&tp)
level, exist := LogLevelMapping[tp]
@ -54,7 +54,7 @@ func (l LogLevel) MarshalJSON() ([]byte, error) {
}
// MarshalYAML serialize LogLevel with yaml
func (l LogLevel) MarshalYAML() (interface{}, error) {
func (l LogLevel) MarshalYAML() (any, error) {
return l.String(), nil
}

View file

@ -10,7 +10,7 @@ import (
)
var (
logCh = make(chan interface{})
logCh = make(chan any)
source = observable.NewObservable(logCh)
level = INFO
)
@ -29,31 +29,31 @@ func (e *Event) Type() string {
return e.LogLevel.String()
}
func Infoln(format string, v ...interface{}) {
func Infoln(format string, v ...any) {
event := newLog(INFO, format, v...)
logCh <- event
print(event)
}
func Warnln(format string, v ...interface{}) {
func Warnln(format string, v ...any) {
event := newLog(WARNING, format, v...)
logCh <- event
print(event)
}
func Errorln(format string, v ...interface{}) {
func Errorln(format string, v ...any) {
event := newLog(ERROR, format, v...)
logCh <- event
print(event)
}
func Debugln(format string, v ...interface{}) {
func Debugln(format string, v ...any) {
event := newLog(DEBUG, format, v...)
logCh <- event
print(event)
}
func Fatalln(format string, v ...interface{}) {
func Fatalln(format string, v ...any) {
log.Fatalf(format, v...)
}
@ -91,7 +91,7 @@ func print(data *Event) {
}
}
func newLog(logLevel LogLevel, format string, v ...interface{}) *Event {
func newLog(logLevel LogLevel, format string, v ...any) *Event {
return &Event{
LogLevel: logLevel,
Payload: fmt.Sprintf(format, v...),

View file

@ -48,7 +48,7 @@ func init() {
}
func main() {
_, _ = maxprocs.Set(maxprocs.Logger(func(string, ...interface{}) {}))
maxprocs.Set(maxprocs.Logger(func(string, ...any) {}))
if version {
fmt.Printf("Clash Meta %s %s %s with %s %s\n", C.Version, runtime.GOOS, runtime.GOARCH, runtime.Version(), C.BuildTime)
return

View file

@ -1,30 +1,33 @@
module clash-test
go 1.17
go 1.18
require (
github.com/Dreamacro/clash v1.7.2-0.20211108085948-bd2ea2b917aa
github.com/docker/docker v20.10.12+incompatible
github.com/docker/docker v20.10.13+incompatible
github.com/docker/go-connections v0.4.0
github.com/miekg/dns v1.1.45
github.com/stretchr/testify v1.7.0
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
github.com/miekg/dns v1.1.47
github.com/stretchr/testify v1.7.1
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
)
replace github.com/Dreamacro/clash => ../
require (
github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/containerd/containerd v1.5.8 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/containerd/containerd v1.6.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/insomniacslk/dhcp v0.0.0-20220119180841-3c283ff8b7dd // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 // indirect
github.com/kr328/tun2socket v0.0.0-20210412191540-3d56c47e2d99 // indirect
@ -32,7 +35,7 @@ require (
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/oschwald/geoip2-golang v1.5.0 // indirect
github.com/oschwald/geoip2-golang v1.6.1 // indirect
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
@ -42,16 +45,16 @@ require (
github.com/yaling888/go-lwip v0.0.0-20211103185822-c9d650538091 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/text v0.3.6 // indirect
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect
google.golang.org/grpc v1.43.0 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
google.golang.org/grpc v1.45.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 // indirect
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b // indirect
@ -61,6 +64,8 @@ require (
google.golang.org/grpc v1.42.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gotest.tools/v3 v3.1.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
gvisor.dev/gvisor v0.0.0-20211104052249-2de3450f76d6 // indirect
)

View file

@ -37,7 +37,7 @@ func TestClash_SnellObfsHTTP(t *testing.T) {
Server: localIP.String(),
Port: 10002,
Psk: "password",
ObfsOpts: map[string]interface{}{
ObfsOpts: map[string]any{
"mode": "http",
},
})
@ -74,7 +74,7 @@ func TestClash_SnellObfsTLS(t *testing.T) {
Server: localIP.String(),
Port: 10002,
Psk: "password",
ObfsOpts: map[string]interface{}{
ObfsOpts: map[string]any{
"mode": "tls",
},
})
@ -181,7 +181,7 @@ func Benchmark_Snell(b *testing.B) {
Server: localIP.String(),
Port: 10002,
Psk: "password",
ObfsOpts: map[string]interface{}{
ObfsOpts: map[string]any{
"mode": "http",
},
})

View file

@ -76,7 +76,7 @@ func TestClash_ShadowsocksObfsHTTP(t *testing.T) {
Cipher: "chacha20-ietf-poly1305",
UDP: true,
Plugin: "obfs",
PluginOpts: map[string]interface{}{
PluginOpts: map[string]any{
"mode": "http",
},
})
@ -118,7 +118,7 @@ func TestClash_ShadowsocksObfsTLS(t *testing.T) {
Cipher: "chacha20-ietf-poly1305",
UDP: true,
Plugin: "obfs",
PluginOpts: map[string]interface{}{
PluginOpts: map[string]any{
"mode": "tls",
},
})
@ -160,7 +160,7 @@ func TestClash_ShadowsocksV2RayPlugin(t *testing.T) {
Cipher: "chacha20-ietf-poly1305",
UDP: true,
Plugin: "v2ray-plugin",
PluginOpts: map[string]interface{}{
PluginOpts: map[string]any{
"mode": "websocket",
},
})

View file

@ -1,5 +1,4 @@
//go:build !darwin
// +build !darwin
package main

View file

@ -71,12 +71,12 @@ func (pc *PoolConn) Close() error {
func NewPool(factory func(context.Context) (*Snell, error)) *Pool {
p := pool.New(
func(ctx context.Context) (interface{}, error) {
func(ctx context.Context) (any, error) {
return factory(ctx)
},
pool.WithAge(15000),
pool.WithSize(10),
pool.WithEvict(func(item interface{}) {
pool.WithEvict(func(item any) {
item.(*Snell).Close()
}),
)

View file

@ -36,7 +36,7 @@ func (m *TunnelMode) UnmarshalJSON(data []byte) error {
}
// UnmarshalYAML unserialize Mode with yaml
func (m *TunnelMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
func (m *TunnelMode) UnmarshalYAML(unmarshal func(any) error) error {
var tp string
unmarshal(&tp)
mode, exist := ModeMapping[strings.ToLower(tp)]
@ -53,7 +53,7 @@ func (m TunnelMode) MarshalJSON() ([]byte, error) {
}
// MarshalYAML serialize TunnelMode with yaml
func (m TunnelMode) MarshalYAML() (interface{}, error) {
func (m TunnelMode) MarshalYAML() (any, error) {
return m.String(), nil
}

View file

@ -56,7 +56,7 @@ func (m *Manager) Now() (up int64, down int64) {
func (m *Manager) Snapshot() *Snapshot {
connections := []tracker{}
m.connections.Range(func(key, value interface{}) bool {
m.connections.Range(func(key, value any) bool {
connections = append(connections, value.(tracker))
return true
})