mirror of https://github.com/Dreamacro/clash.git
Fix: parse error in proxyGroupsDagSort (#298)
This commit is contained in:
parent
112b3e5a6c
commit
b3e10c05e6
|
@ -193,3 +193,9 @@ func (p *Proxy) URLTest(ctx context.Context, url string) (t uint16, err error) {
|
||||||
func NewProxy(adapter C.ProxyAdapter) *Proxy {
|
func NewProxy(adapter C.ProxyAdapter) *Proxy {
|
||||||
return &Proxy{adapter, queue.New(10), true}
|
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
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
adapters "github.com/Dreamacro/clash/adapters/outbound"
|
||||||
|
"github.com/Dreamacro/clash/common/structure"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
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.
|
// Check if ProxyGroups form DAG(Directed Acyclic Graph), and sort all ProxyGroups by dependency order.
|
||||||
// Meanwhile, record the original index in the config file.
|
// Meanwhile, record the original index in the config file.
|
||||||
// If loop is detected, return an error with location of loop.
|
// 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
|
indegree int
|
||||||
// topological order
|
// topological order
|
||||||
topo int
|
topo int
|
||||||
|
@ -51,32 +53,31 @@ func proxyGroupsDagSort(groupsConfig []map[string]interface{}) error {
|
||||||
from []string
|
from []string
|
||||||
}
|
}
|
||||||
|
|
||||||
graph := make(map[string]*Node)
|
graph := make(map[string]*graphNode)
|
||||||
|
|
||||||
// Step 1.1 build dependency graph
|
// Step 1.1 build dependency graph
|
||||||
for idx, mapping := range groupsConfig {
|
for _, mapping := range groupsConfig {
|
||||||
groupName, existName := mapping["name"].(string)
|
option := &adapters.ProxyGroupOption{}
|
||||||
if !existName {
|
err := decoder.Decode(mapping, option)
|
||||||
return fmt.Errorf("ProxyGroup %d: missing name", idx)
|
groupName := option.Name
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ProxyGroup %s: %s", groupName, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if node, ok := graph[groupName]; ok {
|
if node, ok := graph[groupName]; ok {
|
||||||
if node.data != nil {
|
if node.data != nil {
|
||||||
return fmt.Errorf("ProxyGroup %s: duplicate group name", groupName)
|
return fmt.Errorf("ProxyGroup %s: duplicate group name", groupName)
|
||||||
}
|
}
|
||||||
node.data = mapping
|
node.data = mapping
|
||||||
} else {
|
} else {
|
||||||
graph[groupName] = &Node{0, -1, mapping, 0, nil}
|
graph[groupName] = &graphNode{0, -1, mapping, 0, nil}
|
||||||
}
|
}
|
||||||
proxies, existProxies := mapping["proxies"]
|
|
||||||
if !existProxies {
|
for _, proxy := range option.Proxies {
|
||||||
return fmt.Errorf("ProxyGroup %s: the `proxies` field is requried", groupName)
|
|
||||||
}
|
|
||||||
for _, proxy := range proxies.([]interface{}) {
|
|
||||||
proxy := proxy.(string)
|
|
||||||
if node, ex := graph[proxy]; ex {
|
if node, ex := graph[proxy]; ex {
|
||||||
node.indegree++
|
node.indegree++
|
||||||
} else {
|
} else {
|
||||||
graph[proxy] = &Node{1, -1, nil, 0, nil}
|
graph[proxy] = &graphNode{1, -1, nil, 0, nil}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue