Fix: parse error in proxyGroupsDagSort (#298)
This commit is contained in:
parent
eb341b8721
commit
3663e583f4
3 changed files with 23 additions and 16 deletions
|
@ -193,3 +193,9 @@ func (p *Proxy) URLTest(ctx context.Context, url string) (t uint16, err error) {
|
|||
func NewProxy(adapter C.ProxyAdapter) *Proxy {
|
||||
return &Proxy{adapter, queue.New(10), true}
|
||||
}
|
||||
|
||||
// ProxyGroupOption contain the common options for all kind of ProxyGroup
|
||||
type ProxyGroupOption struct {
|
||||
Name string `proxy:"name"`
|
||||
Proxies []string `proxy:"proxies"`
|
||||
}
|
||||
|
|
|
@ -302,7 +302,7 @@ func parseProxies(cfg *rawConfig) (map[string]C.Proxy, error) {
|
|||
}
|
||||
|
||||
// check if any loop exists and sort the ProxyGroups
|
||||
if err := proxyGroupsDagSort(groupsConfig); err != nil {
|
||||
if err := proxyGroupsDagSort(groupsConfig, decoder); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
adapters "github.com/Dreamacro/clash/adapters/outbound"
|
||||
"github.com/Dreamacro/clash/common/structure"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
|
@ -38,9 +40,9 @@ func or(pointers ...*int) *int {
|
|||
// 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]interface{}, decoder *structure.Decoder) error {
|
||||
|
||||
type Node struct {
|
||||
type graphNode struct {
|
||||
indegree int
|
||||
// topological order
|
||||
topo int
|
||||
|
@ -51,32 +53,31 @@ func proxyGroupsDagSort(groupsConfig []map[string]interface{}) error {
|
|||
from []string
|
||||
}
|
||||
|
||||
graph := make(map[string]*Node)
|
||||
graph := make(map[string]*graphNode)
|
||||
|
||||
// Step 1.1 build dependency graph
|
||||
for idx, mapping := range groupsConfig {
|
||||
groupName, existName := mapping["name"].(string)
|
||||
if !existName {
|
||||
return fmt.Errorf("ProxyGroup %d: missing name", idx)
|
||||
for _, mapping := range groupsConfig {
|
||||
option := &adapters.ProxyGroupOption{}
|
||||
err := decoder.Decode(mapping, option)
|
||||
groupName := option.Name
|
||||
if err != nil {
|
||||
return fmt.Errorf("ProxyGroup %s: %s", groupName, err.Error())
|
||||
}
|
||||
|
||||
if node, ok := graph[groupName]; ok {
|
||||
if node.data != nil {
|
||||
return fmt.Errorf("ProxyGroup %s: duplicate group name", groupName)
|
||||
}
|
||||
node.data = mapping
|
||||
} else {
|
||||
graph[groupName] = &Node{0, -1, mapping, 0, nil}
|
||||
graph[groupName] = &graphNode{0, -1, mapping, 0, nil}
|
||||
}
|
||||
proxies, existProxies := mapping["proxies"]
|
||||
if !existProxies {
|
||||
return fmt.Errorf("ProxyGroup %s: the `proxies` field is requried", groupName)
|
||||
}
|
||||
for _, proxy := range proxies.([]interface{}) {
|
||||
proxy := proxy.(string)
|
||||
|
||||
for _, proxy := range option.Proxies {
|
||||
if node, ex := graph[proxy]; ex {
|
||||
node.indegree++
|
||||
} else {
|
||||
graph[proxy] = &Node{1, -1, nil, 0, nil}
|
||||
graph[proxy] = &graphNode{1, -1, nil, 0, nil}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue