diff --git a/common/utils/slice.go b/common/utils/slice.go index fa8eef9b..1b0fa494 100644 --- a/common/utils/slice.go +++ b/common/utils/slice.go @@ -1,5 +1,11 @@ package utils +import ( + "errors" + "fmt" + "reflect" +) + func Filter[T comparable](tSlice []T, filter func(t T) bool) []T { result := make([]T, 0) for _, t := range tSlice { @@ -9,3 +15,20 @@ func Filter[T comparable](tSlice []T, filter func(t T) bool) []T { } return result } + +func ToStringSlice(value any) ([]string, error) { + strArr := make([]string, 0) + switch reflect.TypeOf(value).Kind() { + case reflect.Slice, reflect.Array: + origin := reflect.ValueOf(value) + for i := 0; i < origin.Len(); i++ { + item := fmt.Sprintf("%v", origin.Index(i)) + strArr = append(strArr, item) + } + case reflect.String: + strArr = append(strArr, fmt.Sprintf("%v", value)) + default: + return nil, errors.New("value format error, must be string or array") + } + return strArr, nil +} diff --git a/component/resolver/host.go b/component/resolver/host.go index 135d35db..0b98bd68 100644 --- a/component/resolver/host.go +++ b/component/resolver/host.go @@ -2,11 +2,11 @@ package resolver import ( "errors" - "fmt" "math/rand" "net/netip" - "reflect" "strings" + + "github.com/Dreamacro/clash/common/utils" ) type HostValue struct { @@ -19,27 +19,27 @@ func NewHostValue(value any) (HostValue, error) { isDomain := true ips := make([]netip.Addr, 0) domain := "" - switch reflect.TypeOf(value).Kind() { - case reflect.Slice, reflect.Array: - isDomain = false - origin := reflect.ValueOf(value) - for i := 0; i < origin.Len(); i++ { - if ip, err := netip.ParseAddr(fmt.Sprintf("%v", origin.Index(i))); err == nil { + if valueArr, err := utils.ToStringSlice(value); err != nil { + return HostValue{}, err + } else { + if len(valueArr) > 1 { + isDomain=false + for _, str := range valueArr { + if ip, err := netip.ParseAddr(str); err == nil { + ips = append(ips, ip) + } else { + return HostValue{}, err + } + } + } else if len(valueArr) == 1 { + host := valueArr[0] + if ip, err := netip.ParseAddr(host); err == nil { ips = append(ips, ip) + isDomain = false } else { - return HostValue{}, err + domain = host } } - case reflect.String: - host := fmt.Sprintf("%v", value) - if ip, err := netip.ParseAddr(host); err == nil { - ips = append(ips, ip) - isDomain = false - } else { - domain = host - } - default: - return HostValue{}, errors.New("value format error, must be string or array") } if isDomain { return NewHostValueByDomain(domain) diff --git a/config/config.go b/config/config.go index 778d56c5..b29144c4 100644 --- a/config/config.go +++ b/config/config.go @@ -9,7 +9,6 @@ import ( "net/netip" "net/url" "os" - "reflect" "runtime" "strconv" "strings" @@ -852,7 +851,7 @@ func parseHosts(cfg *RawConfig) (*trie.DomainTrie[resolver.HostValue], error) { } } } - anyValue=ips + anyValue = ips } } value, err := resolver.NewHostValue(anyValue) @@ -988,24 +987,12 @@ func parseNameServerPolicy(nsPolicy map[string]any, preferH3 bool) (map[string][ policy := map[string][]dns.NameServer{} for domain, server := range nsPolicy { - var ( - nameservers []dns.NameServer - err error - ) - switch reflect.TypeOf(server).Kind() { - case reflect.Slice, reflect.Array: - origin := reflect.ValueOf(server) - servers := make([]string, 0) - for i := 0; i < origin.Len(); i++ { - servers = append(servers, fmt.Sprintf("%v", origin.Index(i))) - } - nameservers, err = parseNameServer(servers, preferH3) - case reflect.String: - nameservers, err = parseNameServer([]string{fmt.Sprintf("%v", server)}, preferH3) - default: - return nil, errors.New("server format error, must be string or array") + servers, err := utils.ToStringSlice(server) + if err != nil { + return nil, err } + nameservers, err := parseNameServer(servers, preferH3) if err != nil { return nil, err }