From a5d54884e0a281030ec9a4ba44384cf948a75c6c Mon Sep 17 00:00:00 2001 From: Dreamacro <8615343+Dreamacro@users.noreply.github.com> Date: Sun, 1 Jan 2023 20:12:17 +0800 Subject: [PATCH] Feature: add `udp-fallback-match` option --- config/config.go | 7 ++++++- hub/executor/executor.go | 4 +++- tunnel/tunnel.go | 9 +++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/config/config.go b/config/config.go index d906341..4bd651c 100644 --- a/config/config.go +++ b/config/config.go @@ -86,7 +86,9 @@ type Profile struct { } // Experimental config -type Experimental struct{} +type Experimental struct { + UDPFallbackMatch bool `yaml:"udp-fallback-match"` +} // Config is clash config manager type Config struct { @@ -250,6 +252,9 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) { Profile: Profile{ StoreSelected: true, }, + Experimental: Experimental{ + UDPFallbackMatch: true, + }, } if err := yaml.Unmarshal(buf, rawCfg); err != nil { diff --git a/hub/executor/executor.go b/hub/executor/executor.go index a131f4b..8f94bc7 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -104,7 +104,9 @@ func GetGeneral() *config.General { return general } -func updateExperimental(c *config.Config) {} +func updateExperimental(c *config.Config) { + tunnel.UDPFallbackMatch.Store(c.Experimental.UDPFallbackMatch) +} func updateDNS(c *config.DNS) { if !c.Enable { diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index bf09f23..20e03fd 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -19,6 +19,8 @@ import ( icontext "github.com/Dreamacro/clash/context" "github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/tunnel/statistic" + + "go.uber.org/atomic" ) var ( @@ -35,6 +37,9 @@ var ( // default timeout for UDP session udpTimeout = 60 * time.Second + + // experimental feature + UDPFallbackMatch = atomic.NewBool(false) ) func init() { @@ -407,8 +412,8 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { continue } - if metadata.NetWork == C.UDP && !adapter.SupportUDP() { - log.Debugln("%s UDP is not supported", adapter.Name()) + if metadata.NetWork == C.UDP && !adapter.SupportUDP() && UDPFallbackMatch.Load() { + log.Debugln("[Matcher] %s UDP is not supported, skip match", adapter.Name()) continue } return adapter, rule, nil