chore: cleanup the patch code

This commit is contained in:
wwqgtxx 2024-09-11 16:10:35 +08:00
parent 8230bc8e7d
commit 0a2f606e1b
18 changed files with 122 additions and 185 deletions

View File

@ -9,7 +9,6 @@ import (
"github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/component/resource" "github.com/metacubex/mihomo/component/resource"
C "github.com/metacubex/mihomo/constant" C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
types "github.com/metacubex/mihomo/constant/provider" types "github.com/metacubex/mihomo/constant/provider"
) )
@ -94,7 +93,7 @@ func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvide
path := C.Path.GetPathByHash("proxies", schema.URL) path := C.Path.GetPathByHash("proxies", schema.URL)
if schema.Path != "" { if schema.Path != "" {
path = C.Path.Resolve(schema.Path) path = C.Path.Resolve(schema.Path)
if !features.CMFA && !C.Path.IsSafePath(path) { if !C.Path.IsSafePath(path) {
return nil, fmt.Errorf("%w: %s", errSubPath, path) return nil, fmt.Errorf("%w: %s", errSubPath, path)
} }
} }

View File

@ -33,15 +33,8 @@ type ARC[K comparable, V any] struct {
// New returns a new Adaptive Replacement Cache (ARC). // New returns a new Adaptive Replacement Cache (ARC).
func New[K comparable, V any](options ...Option[K, V]) *ARC[K, V] { func New[K comparable, V any](options ...Option[K, V]) *ARC[K, V] {
arc := &ARC[K, V]{ arc := &ARC[K, V]{}
p: 0, arc.Clear()
t1: list.New[*entry[K, V]](),
b1: list.New[*entry[K, V]](),
t2: list.New[*entry[K, V]](),
b2: list.New[*entry[K, V]](),
len: 0,
cache: make(map[K]*entry[K, V]),
}
for _, option := range options { for _, option := range options {
option(arc) option(arc)
@ -49,6 +42,19 @@ func New[K comparable, V any](options ...Option[K, V]) *ARC[K, V] {
return arc return arc
} }
func (a *ARC[K, V]) Clear() {
a.mutex.Lock()
defer a.mutex.Unlock()
a.p = 0
a.t1 = list.New[*entry[K, V]]()
a.b1 = list.New[*entry[K, V]]()
a.t2 = list.New[*entry[K, V]]()
a.b2 = list.New[*entry[K, V]]()
a.len = 0
a.cache = make(map[K]*entry[K, V])
}
// Set inserts a new key-value pair into the cache. // Set inserts a new key-value pair into the cache.
// This optimizes future access to this entry (side effect). // This optimizes future access to this entry (side effect).
func (a *ARC[K, V]) Set(key K, value V) { func (a *ARC[K, V]) Set(key K, value V) {

View File

@ -68,10 +68,8 @@ type LruCache[K comparable, V any] struct {
// New creates an LruCache // New creates an LruCache
func New[K comparable, V any](options ...Option[K, V]) *LruCache[K, V] { func New[K comparable, V any](options ...Option[K, V]) *LruCache[K, V] {
lc := &LruCache[K, V]{ lc := &LruCache[K, V]{}
lru: list.New[*entry[K, V]](), lc.Clear()
cache: make(map[K]*list.Element[*entry[K, V]]),
}
for _, option := range options { for _, option := range options {
option(lc) option(lc)
@ -80,6 +78,14 @@ func New[K comparable, V any](options ...Option[K, V]) *LruCache[K, V] {
return lc return lc
} }
func (c *LruCache[K, V]) Clear() {
c.mu.Lock()
defer c.mu.Unlock()
c.lru = list.New[*entry[K, V]]()
c.cache = make(map[K]*list.Element[*entry[K, V]])
}
// Get returns any representation of a cached response and a bool // Get returns any representation of a cached response and a bool
// set to true if the key was found. // set to true if the key was found.
func (c *LruCache[K, V]) Get(key K) (V, bool) { func (c *LruCache[K, V]) Get(key K) (V, bool) {
@ -250,15 +256,6 @@ func (c *LruCache[K, V]) deleteElement(le *list.Element[*entry[K, V]]) {
} }
} }
func (c *LruCache[K, V]) Clear() error {
c.mu.Lock()
defer c.mu.Unlock()
c.cache = make(map[K]*list.Element[*entry[K, V]])
return nil
}
// Compute either sets the computed new value for the key or deletes // Compute either sets the computed new value for the key or deletes
// the value for the key. When the delete result of the valueFn function // the value for the key. When the delete result of the valueFn function
// is set to true, the value will be deleted, if it exists. When delete // is set to true, the value will be deleted, if it exists. When delete

View File

@ -67,8 +67,9 @@ func (m *memoryStore) CloneTo(store store) {
// FlushFakeIP implements store.FlushFakeIP // FlushFakeIP implements store.FlushFakeIP
func (m *memoryStore) FlushFakeIP() error { func (m *memoryStore) FlushFakeIP() error {
_ = m.cacheIP.Clear() m.cacheIP.Clear()
return m.cacheHost.Clear() m.cacheHost.Clear()
return nil
} }
func newMemoryStore(size int) *memoryStore { func newMemoryStore(size int) *memoryStore {

View File

@ -1,18 +0,0 @@
//go:build android && cmfa
package mmdb
import "github.com/oschwald/maxminddb-golang"
func InstallOverride(override *maxminddb.Reader) {
newReader := IPReader{Reader: override}
switch override.Metadata.DatabaseType {
case "sing-geoip":
ipReader.databaseType = typeSing
case "Meta-geoip0":
ipReader.databaseType = typeMetaV0
default:
ipReader.databaseType = typeMaxmind
}
ipReader = newReader
}

View File

@ -46,6 +46,7 @@ type Resolver interface {
LookupIPv6(ctx context.Context, host string) (ips []netip.Addr, err error) LookupIPv6(ctx context.Context, host string) (ips []netip.Addr, err error)
ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error) ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error)
Invalid() bool Invalid() bool
ClearCache()
} }
// LookupIPv4WithResolver same as LookupIPv4, but with a resolver // LookupIPv4WithResolver same as LookupIPv4, but with a resolver

View File

@ -30,7 +30,6 @@ import (
"github.com/metacubex/mihomo/component/trie" "github.com/metacubex/mihomo/component/trie"
"github.com/metacubex/mihomo/component/updater" "github.com/metacubex/mihomo/component/updater"
C "github.com/metacubex/mihomo/constant" C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
providerTypes "github.com/metacubex/mihomo/constant/provider" providerTypes "github.com/metacubex/mihomo/constant/provider"
snifferTypes "github.com/metacubex/mihomo/constant/sniffer" snifferTypes "github.com/metacubex/mihomo/constant/sniffer"
"github.com/metacubex/mihomo/dns" "github.com/metacubex/mihomo/dns"
@ -649,7 +648,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
config.DNS = dnsCfg config.DNS = dnsCfg
err = parseTun(rawCfg.Tun, config.General) err = parseTun(rawCfg.Tun, config.General)
if !features.CMFA && err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -8,6 +8,8 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"github.com/metacubex/mihomo/constant/features"
) )
const Name = "mihomo" const Name = "mihomo"
@ -73,7 +75,7 @@ func (p *path) Resolve(path string) string {
// IsSafePath return true if path is a subpath of homedir // IsSafePath return true if path is a subpath of homedir
func (p *path) IsSafePath(path string) bool { func (p *path) IsSafePath(path string) bool {
if p.allowUnsafePath { if p.allowUnsafePath || features.CMFA {
return true return true
} }
homedir := p.HomeDir() homedir := p.HomeDir()

View File

@ -1,5 +1,3 @@
//go:build !(android && cmfa)
package dns package dns
import ( import (

View File

@ -3,53 +3,16 @@
package dns package dns
import ( import (
"context"
D "github.com/miekg/dns"
"github.com/metacubex/mihomo/common/lru"
"github.com/metacubex/mihomo/component/dhcp"
"github.com/metacubex/mihomo/component/resolver" "github.com/metacubex/mihomo/component/resolver"
) )
const SystemDNSPlaceholder = "system" const SystemDNSPlaceholder = "system"
var systemResolver *Resolver var systemResolver []dnsClient
var isolateHandler handler
var _ dnsClient = (*dhcpClient)(nil)
type dhcpClient struct {
enable bool
}
func (d *dhcpClient) Address() string {
return SystemDNSPlaceholder
}
func (d *dhcpClient) Exchange(m *D.Msg) (msg *D.Msg, err error) {
return d.ExchangeContext(context.Background(), m)
}
func (d *dhcpClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
if s := systemResolver; s != nil {
return s.ExchangeContext(ctx, m)
}
return nil, dhcp.ErrNotFound
}
func ServeDNSWithDefaultServer(msg *D.Msg) (*D.Msg, error) {
if h := isolateHandler; h != nil {
return handlerWithContext(context.Background(), h, msg)
}
return nil, D.ErrTime
}
func FlushCacheWithDefaultResolver() { func FlushCacheWithDefaultResolver() {
if r := resolver.DefaultResolver; r != nil { if r := resolver.DefaultResolver; r != nil {
r.(*Resolver).cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) r.ClearCache()
} }
} }
@ -63,19 +26,9 @@ func UpdateSystemDNS(addr []string) {
ns = append(ns, NameServer{Addr: d}) ns = append(ns, NameServer{Addr: d})
} }
systemResolver = NewResolver(Config{Main: ns}) systemResolver = transform(ns, nil)
} }
func UpdateIsolateHandler(resolver *Resolver, mapper *ResolverEnhancer) { func (c *systemClient) getDnsClients() ([]dnsClient, error) {
if resolver == nil { return systemResolver, nil
isolateHandler = nil
return
}
isolateHandler = NewHandler(resolver, mapper)
}
func newDHCPClient(ifaceName string) *dhcpClient {
return &dhcpClient{enable: ifaceName == SystemDNSPlaceholder}
} }

View File

@ -1,6 +0,0 @@
//go:build !(android && cmfa)
package dns
func UpdateIsolateHandler(resolver *Resolver, mapper *ResolverEnhancer) {
}

View File

@ -29,6 +29,7 @@ type dnsClient interface {
type dnsCache interface { type dnsCache interface {
GetWithExpire(key string) (*D.Msg, time.Time, bool) GetWithExpire(key string) (*D.Msg, time.Time, bool)
SetWithExpire(key string, value *D.Msg, expire time.Time) SetWithExpire(key string, value *D.Msg, expire time.Time)
Clear()
} }
type result struct { type result struct {
@ -369,6 +370,12 @@ func (r *Resolver) Invalid() bool {
return len(r.main) > 0 return len(r.main) > 0
} }
func (r *Resolver) ClearCache() {
if r != nil && r.cache != nil {
r.cache.Clear()
}
}
type NameServer struct { type NameServer struct {
Net string Net string
Addr string Addr string

View File

@ -6,7 +6,6 @@ import (
"net" "net"
"github.com/metacubex/mihomo/common/sockopt" "github.com/metacubex/mihomo/common/sockopt"
"github.com/metacubex/mihomo/constant/features"
"github.com/metacubex/mihomo/context" "github.com/metacubex/mihomo/context"
"github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/log"
@ -50,10 +49,6 @@ func (s *Server) SetHandler(handler handler) {
} }
func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) { func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) {
if features.CMFA {
UpdateIsolateHandler(resolver, mapper)
}
if addr == address && resolver != nil { if addr == address && resolver != nil {
handler := NewHandler(resolver, mapper) handler := NewHandler(resolver, mapper)
server.SetHandler(handler) server.SetHandler(handler)

View File

@ -3,16 +3,11 @@ package dns
import ( import (
"context" "context"
"fmt" "fmt"
"net"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/metacubex/mihomo/component/resolver"
"github.com/metacubex/mihomo/log"
D "github.com/miekg/dns" D "github.com/miekg/dns"
"golang.org/x/exp/slices"
) )
const ( const (
@ -31,64 +26,6 @@ type systemClient struct {
lastFlush time.Time lastFlush time.Time
} }
func (c *systemClient) getDnsClients() ([]dnsClient, error) {
c.mu.Lock()
defer c.mu.Unlock()
var err error
if time.Since(c.lastFlush) > SystemDnsFlushTime {
var nameservers []string
if nameservers, err = dnsReadConfig(); err == nil {
log.Debugln("[DNS] system dns update to %s", nameservers)
for _, addr := range nameservers {
if resolver.IsSystemDnsBlacklisted(addr) {
continue
}
if _, ok := c.dnsClients[addr]; !ok {
clients := transform(
[]NameServer{{
Addr: net.JoinHostPort(addr, "53"),
Net: "udp",
}},
nil,
)
if len(clients) > 0 {
c.dnsClients[addr] = &systemDnsClient{
disableTimes: 0,
dnsClient: clients[0],
}
}
}
}
available := 0
for nameserver, sdc := range c.dnsClients {
if slices.Contains(nameservers, nameserver) {
sdc.disableTimes = 0 // enable
available++
} else {
if sdc.disableTimes > SystemDnsDeleteTimes {
delete(c.dnsClients, nameserver) // drop too old dnsClient
} else {
sdc.disableTimes++
}
}
}
if available > 0 {
c.lastFlush = time.Now()
}
}
}
dnsClients := make([]dnsClient, 0, len(c.dnsClients))
for _, sdc := range c.dnsClients {
if sdc.disableTimes == 0 {
dnsClients = append(dnsClients, sdc.dnsClient)
}
}
if len(dnsClients) > 0 {
return dnsClients, nil
}
return nil, err
}
func (c *systemClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) { func (c *systemClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
dnsClients, err := c.getDnsClients() dnsClients, err := c.getDnsClients()
if err != nil { if err != nil {

71
dns/system_common.go Normal file
View File

@ -0,0 +1,71 @@
//go:build !(android && cmfa)
package dns
import (
"net"
"time"
"github.com/metacubex/mihomo/component/resolver"
"github.com/metacubex/mihomo/log"
"golang.org/x/exp/slices"
)
func (c *systemClient) getDnsClients() ([]dnsClient, error) {
c.mu.Lock()
defer c.mu.Unlock()
var err error
if time.Since(c.lastFlush) > SystemDnsFlushTime {
var nameservers []string
if nameservers, err = dnsReadConfig(); err == nil {
log.Debugln("[DNS] system dns update to %s", nameservers)
for _, addr := range nameservers {
if resolver.IsSystemDnsBlacklisted(addr) {
continue
}
if _, ok := c.dnsClients[addr]; !ok {
clients := transform(
[]NameServer{{
Addr: net.JoinHostPort(addr, "53"),
Net: "udp",
}},
nil,
)
if len(clients) > 0 {
c.dnsClients[addr] = &systemDnsClient{
disableTimes: 0,
dnsClient: clients[0],
}
}
}
}
available := 0
for nameserver, sdc := range c.dnsClients {
if slices.Contains(nameservers, nameserver) {
sdc.disableTimes = 0 // enable
available++
} else {
if sdc.disableTimes > SystemDnsDeleteTimes {
delete(c.dnsClients, nameserver) // drop too old dnsClient
} else {
sdc.disableTimes++
}
}
}
if available > 0 {
c.lastFlush = time.Now()
}
}
}
dnsClients := make([]dnsClient, 0, len(c.dnsClients))
for _, sdc := range c.dnsClients {
if sdc.disableTimes == 0 {
dnsClients = append(dnsClients, sdc.dnsClient)
}
}
if len(dnsClients) > 0 {
return dnsClients, nil
}
return nil, err
}

View File

@ -99,6 +99,10 @@ func transform(servers []NameServer, resolver *Resolver) []dnsClient {
ret = append(ret, newDoHClient(s.Addr, resolver, s.PreferH3, s.Params, s.ProxyAdapter, s.ProxyName)) ret = append(ret, newDoHClient(s.Addr, resolver, s.PreferH3, s.Params, s.ProxyAdapter, s.ProxyName))
continue continue
case "dhcp": case "dhcp":
if s.Addr == "system" { // Compatible with old writing
ret = append(ret, newSystemClient())
continue
}
ret = append(ret, newDHCPClient(s.Addr)) ret = append(ret, newDHCPClient(s.Addr))
continue continue
case "system": case "system":

View File

@ -1,10 +1,7 @@
package hub package hub
import ( import (
"strings"
"github.com/metacubex/mihomo/config" "github.com/metacubex/mihomo/config"
"github.com/metacubex/mihomo/constant/features"
"github.com/metacubex/mihomo/hub/executor" "github.com/metacubex/mihomo/hub/executor"
"github.com/metacubex/mihomo/hub/route" "github.com/metacubex/mihomo/hub/route"
"github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/log"
@ -43,11 +40,6 @@ func ApplyConfig(cfg *config.Config) {
} }
func applyRoute(cfg *config.Config) { func applyRoute(cfg *config.Config) {
if features.CMFA && strings.HasSuffix(cfg.Controller.ExternalUI, ":0") {
// CMFA have set its default override value to end with ":0" for security.
// so we direct return at here
return
}
if cfg.Controller.ExternalUI != "" { if cfg.Controller.ExternalUI != "" {
route.SetUIPath(cfg.Controller.ExternalUI) route.SetUIPath(cfg.Controller.ExternalUI)
} }

View File

@ -8,7 +8,6 @@ import (
"github.com/metacubex/mihomo/common/structure" "github.com/metacubex/mihomo/common/structure"
"github.com/metacubex/mihomo/component/resource" "github.com/metacubex/mihomo/component/resource"
C "github.com/metacubex/mihomo/constant" C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
P "github.com/metacubex/mihomo/constant/provider" P "github.com/metacubex/mihomo/constant/provider"
) )
@ -50,7 +49,7 @@ func ParseRuleProvider(name string, mapping map[string]interface{}, parse func(t
path := C.Path.GetPathByHash("rules", schema.URL) path := C.Path.GetPathByHash("rules", schema.URL)
if schema.Path != "" { if schema.Path != "" {
path = C.Path.Resolve(schema.Path) path = C.Path.Resolve(schema.Path)
if !features.CMFA && !C.Path.IsSafePath(path) { if !C.Path.IsSafePath(path) {
return nil, fmt.Errorf("%w: %s", errSubPath, path) return nil, fmt.Errorf("%w: %s", errSubPath, path)
} }
} }