mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 04:13:14 +08:00
Feature: add experimental config for resolving ip fail behavior
This commit is contained in:
parent
90e3dccacd
commit
cec2206774
@ -105,6 +105,10 @@ external-controller: 127.0.0.1:9090
|
|||||||
# Secret for RESTful API (Optional)
|
# Secret for RESTful API (Optional)
|
||||||
# secret: ""
|
# secret: ""
|
||||||
|
|
||||||
|
# experimental feature
|
||||||
|
experimental:
|
||||||
|
ignore-resolve-fail: true # ignore dns reslove fail, default value is true
|
||||||
|
|
||||||
# dns:
|
# dns:
|
||||||
# enable: true # set true to enable dns (default is false)
|
# enable: true # set true to enable dns (default is false)
|
||||||
# ipv6: false # default is false
|
# ipv6: false # default is false
|
||||||
|
@ -43,10 +43,16 @@ type DNS struct {
|
|||||||
EnhancedMode dns.EnhancedMode `yaml:"enhanced-mode"`
|
EnhancedMode dns.EnhancedMode `yaml:"enhanced-mode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Experimental config
|
||||||
|
type Experimental struct {
|
||||||
|
IgnoreResolveFail bool `yaml:"ignore-resolve-fail"`
|
||||||
|
}
|
||||||
|
|
||||||
// Config is clash config manager
|
// Config is clash config manager
|
||||||
type Config struct {
|
type Config struct {
|
||||||
General *General
|
General *General
|
||||||
DNS *DNS
|
DNS *DNS
|
||||||
|
Experimental *Experimental
|
||||||
Rules []C.Rule
|
Rules []C.Rule
|
||||||
Proxies map[string]C.Proxy
|
Proxies map[string]C.Proxy
|
||||||
}
|
}
|
||||||
@ -72,6 +78,7 @@ type rawConfig struct {
|
|||||||
Secret string `yaml:"secret"`
|
Secret string `yaml:"secret"`
|
||||||
|
|
||||||
DNS rawDNS `yaml:"dns"`
|
DNS rawDNS `yaml:"dns"`
|
||||||
|
Experimental Experimental `yaml:"experimental"`
|
||||||
Proxy []map[string]interface{} `yaml:"Proxy"`
|
Proxy []map[string]interface{} `yaml:"Proxy"`
|
||||||
ProxyGroup []map[string]interface{} `yaml:"Proxy Group"`
|
ProxyGroup []map[string]interface{} `yaml:"Proxy Group"`
|
||||||
Rule []string `yaml:"Rule"`
|
Rule []string `yaml:"Rule"`
|
||||||
@ -98,6 +105,9 @@ func readConfig(path string) (*rawConfig, error) {
|
|||||||
Rule: []string{},
|
Rule: []string{},
|
||||||
Proxy: []map[string]interface{}{},
|
Proxy: []map[string]interface{}{},
|
||||||
ProxyGroup: []map[string]interface{}{},
|
ProxyGroup: []map[string]interface{}{},
|
||||||
|
Experimental: Experimental{
|
||||||
|
IgnoreResolveFail: true,
|
||||||
|
},
|
||||||
DNS: rawDNS{
|
DNS: rawDNS{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
},
|
},
|
||||||
@ -114,6 +124,7 @@ func Parse(path string) (*Config, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
config.Experimental = &rawCfg.Experimental
|
||||||
|
|
||||||
general, err := parseGeneral(rawCfg)
|
general, err := parseGeneral(rawCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -27,6 +27,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
|
|||||||
updateProxies(cfg.Proxies)
|
updateProxies(cfg.Proxies)
|
||||||
updateRules(cfg.Rules)
|
updateRules(cfg.Rules)
|
||||||
updateDNS(cfg.DNS)
|
updateDNS(cfg.DNS)
|
||||||
|
updateExperimental(cfg.Experimental)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGeneral() *config.General {
|
func GetGeneral() *config.General {
|
||||||
@ -41,6 +42,10 @@ func GetGeneral() *config.General {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateExperimental(c *config.Experimental) {
|
||||||
|
T.Instance().UpdateExperimental(c.IgnoreResolveFail)
|
||||||
|
}
|
||||||
|
|
||||||
func updateDNS(c *config.DNS) {
|
func updateDNS(c *config.DNS) {
|
||||||
if c.Enable == false {
|
if c.Enable == false {
|
||||||
T.Instance().SetResolver(nil)
|
T.Instance().SetResolver(nil)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
package socks
|
|
@ -24,10 +24,13 @@ type Tunnel struct {
|
|||||||
queue *channels.InfiniteChannel
|
queue *channels.InfiniteChannel
|
||||||
rules []C.Rule
|
rules []C.Rule
|
||||||
proxies map[string]C.Proxy
|
proxies map[string]C.Proxy
|
||||||
configLock *sync.RWMutex
|
configMux *sync.RWMutex
|
||||||
traffic *C.Traffic
|
traffic *C.Traffic
|
||||||
resolver *dns.Resolver
|
resolver *dns.Resolver
|
||||||
|
|
||||||
|
// experimental features
|
||||||
|
ignoreResolveFail bool
|
||||||
|
|
||||||
// Outbound Rule
|
// Outbound Rule
|
||||||
mode Mode
|
mode Mode
|
||||||
}
|
}
|
||||||
@ -49,9 +52,9 @@ func (t *Tunnel) Rules() []C.Rule {
|
|||||||
|
|
||||||
// UpdateRules handle update rules
|
// UpdateRules handle update rules
|
||||||
func (t *Tunnel) UpdateRules(rules []C.Rule) {
|
func (t *Tunnel) UpdateRules(rules []C.Rule) {
|
||||||
t.configLock.Lock()
|
t.configMux.Lock()
|
||||||
t.rules = rules
|
t.rules = rules
|
||||||
t.configLock.Unlock()
|
t.configMux.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proxies return all proxies
|
// Proxies return all proxies
|
||||||
@ -61,9 +64,16 @@ func (t *Tunnel) Proxies() map[string]C.Proxy {
|
|||||||
|
|
||||||
// UpdateProxies handle update proxies
|
// UpdateProxies handle update proxies
|
||||||
func (t *Tunnel) UpdateProxies(proxies map[string]C.Proxy) {
|
func (t *Tunnel) UpdateProxies(proxies map[string]C.Proxy) {
|
||||||
t.configLock.Lock()
|
t.configMux.Lock()
|
||||||
t.proxies = proxies
|
t.proxies = proxies
|
||||||
t.configLock.Unlock()
|
t.configMux.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateExperimental handle update experimental config
|
||||||
|
func (t *Tunnel) UpdateExperimental(ignoreResolveFail bool) {
|
||||||
|
t.configMux.Lock()
|
||||||
|
t.ignoreResolveFail = ignoreResolveFail
|
||||||
|
t.configMux.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mode return current mode
|
// Mode return current mode
|
||||||
@ -174,18 +184,24 @@ func (t *Tunnel) shouldResolveIP(rule C.Rule, metadata *C.Metadata) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tunnel) match(metadata *C.Metadata) (C.Proxy, error) {
|
func (t *Tunnel) match(metadata *C.Metadata) (C.Proxy, error) {
|
||||||
t.configLock.RLock()
|
t.configMux.RLock()
|
||||||
defer t.configLock.RUnlock()
|
defer t.configMux.RUnlock()
|
||||||
|
|
||||||
|
var resolved bool
|
||||||
for _, rule := range t.rules {
|
for _, rule := range t.rules {
|
||||||
if t.shouldResolveIP(rule, metadata) {
|
if !resolved && t.shouldResolveIP(rule, metadata) {
|
||||||
ip, err := t.resolveIP(metadata.Host)
|
ip, err := t.resolveIP(metadata.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if !t.ignoreResolveFail {
|
||||||
return nil, fmt.Errorf("[DNS] resolve %s error: %s", metadata.Host, err.Error())
|
return nil, fmt.Errorf("[DNS] resolve %s error: %s", metadata.Host, err.Error())
|
||||||
}
|
}
|
||||||
|
log.Debugln("[DNS] resolve %s error: %s", metadata.Host, err.Error())
|
||||||
|
} else {
|
||||||
log.Debugln("[DNS] %s --> %s", metadata.Host, ip.String())
|
log.Debugln("[DNS] %s --> %s", metadata.Host, ip.String())
|
||||||
metadata.IP = &ip
|
metadata.IP = &ip
|
||||||
}
|
}
|
||||||
|
resolved = true
|
||||||
|
}
|
||||||
|
|
||||||
if rule.IsMatch(metadata) {
|
if rule.IsMatch(metadata) {
|
||||||
adapter, ok := t.proxies[rule.Adapter()]
|
adapter, ok := t.proxies[rule.Adapter()]
|
||||||
@ -209,7 +225,7 @@ func newTunnel() *Tunnel {
|
|||||||
return &Tunnel{
|
return &Tunnel{
|
||||||
queue: channels.NewInfiniteChannel(),
|
queue: channels.NewInfiniteChannel(),
|
||||||
proxies: make(map[string]C.Proxy),
|
proxies: make(map[string]C.Proxy),
|
||||||
configLock: &sync.RWMutex{},
|
configMux: &sync.RWMutex{},
|
||||||
traffic: C.NewTraffic(time.Second),
|
traffic: C.NewTraffic(time.Second),
|
||||||
mode: Rule,
|
mode: Rule,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user