mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-12-22 23:57:26 +08:00
chore: cleanup the patch code
This commit is contained in:
parent
8230bc8e7d
commit
0a2f606e1b
@ -9,7 +9,6 @@ import (
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
"github.com/metacubex/mihomo/component/resource"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
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)
|
||||
if 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)
|
||||
}
|
||||
}
|
||||
|
@ -33,15 +33,8 @@ type ARC[K comparable, V any] struct {
|
||||
|
||||
// New returns a new Adaptive Replacement Cache (ARC).
|
||||
func New[K comparable, V any](options ...Option[K, V]) *ARC[K, V] {
|
||||
arc := &ARC[K, V]{
|
||||
p: 0,
|
||||
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]),
|
||||
}
|
||||
arc := &ARC[K, V]{}
|
||||
arc.Clear()
|
||||
|
||||
for _, option := range options {
|
||||
option(arc)
|
||||
@ -49,6 +42,19 @@ func New[K comparable, V any](options ...Option[K, V]) *ARC[K, V] {
|
||||
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.
|
||||
// This optimizes future access to this entry (side effect).
|
||||
func (a *ARC[K, V]) Set(key K, value V) {
|
||||
|
@ -68,10 +68,8 @@ type LruCache[K comparable, V any] struct {
|
||||
|
||||
// New creates an LruCache
|
||||
func New[K comparable, V any](options ...Option[K, V]) *LruCache[K, V] {
|
||||
lc := &LruCache[K, V]{
|
||||
lru: list.New[*entry[K, V]](),
|
||||
cache: make(map[K]*list.Element[*entry[K, V]]),
|
||||
}
|
||||
lc := &LruCache[K, V]{}
|
||||
lc.Clear()
|
||||
|
||||
for _, option := range options {
|
||||
option(lc)
|
||||
@ -80,6 +78,14 @@ func New[K comparable, V any](options ...Option[K, V]) *LruCache[K, V] {
|
||||
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
|
||||
// set to true if the key was found.
|
||||
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
|
||||
// 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
|
||||
|
@ -67,8 +67,9 @@ func (m *memoryStore) CloneTo(store store) {
|
||||
|
||||
// FlushFakeIP implements store.FlushFakeIP
|
||||
func (m *memoryStore) FlushFakeIP() error {
|
||||
_ = m.cacheIP.Clear()
|
||||
return m.cacheHost.Clear()
|
||||
m.cacheIP.Clear()
|
||||
m.cacheHost.Clear()
|
||||
return nil
|
||||
}
|
||||
|
||||
func newMemoryStore(size int) *memoryStore {
|
||||
|
@ -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
|
||||
}
|
@ -46,6 +46,7 @@ type Resolver interface {
|
||||
LookupIPv6(ctx context.Context, host string) (ips []netip.Addr, err error)
|
||||
ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error)
|
||||
Invalid() bool
|
||||
ClearCache()
|
||||
}
|
||||
|
||||
// LookupIPv4WithResolver same as LookupIPv4, but with a resolver
|
||||
|
@ -30,7 +30,6 @@ import (
|
||||
"github.com/metacubex/mihomo/component/trie"
|
||||
"github.com/metacubex/mihomo/component/updater"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
providerTypes "github.com/metacubex/mihomo/constant/provider"
|
||||
snifferTypes "github.com/metacubex/mihomo/constant/sniffer"
|
||||
"github.com/metacubex/mihomo/dns"
|
||||
@ -649,7 +648,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
||||
config.DNS = dnsCfg
|
||||
|
||||
err = parseTun(rawCfg.Tun, config.General)
|
||||
if !features.CMFA && err != nil {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
)
|
||||
|
||||
const Name = "mihomo"
|
||||
@ -73,7 +75,7 @@ func (p *path) Resolve(path string) string {
|
||||
|
||||
// IsSafePath return true if path is a subpath of homedir
|
||||
func (p *path) IsSafePath(path string) bool {
|
||||
if p.allowUnsafePath {
|
||||
if p.allowUnsafePath || features.CMFA {
|
||||
return true
|
||||
}
|
||||
homedir := p.HomeDir()
|
||||
|
@ -1,5 +1,3 @@
|
||||
//go:build !(android && cmfa)
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
|
@ -3,53 +3,16 @@
|
||||
package dns
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
const SystemDNSPlaceholder = "system"
|
||||
|
||||
var systemResolver *Resolver
|
||||
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
|
||||
}
|
||||
var systemResolver []dnsClient
|
||||
|
||||
func FlushCacheWithDefaultResolver() {
|
||||
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})
|
||||
}
|
||||
|
||||
systemResolver = NewResolver(Config{Main: ns})
|
||||
systemResolver = transform(ns, nil)
|
||||
}
|
||||
|
||||
func UpdateIsolateHandler(resolver *Resolver, mapper *ResolverEnhancer) {
|
||||
if resolver == nil {
|
||||
isolateHandler = nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
isolateHandler = NewHandler(resolver, mapper)
|
||||
}
|
||||
|
||||
func newDHCPClient(ifaceName string) *dhcpClient {
|
||||
return &dhcpClient{enable: ifaceName == SystemDNSPlaceholder}
|
||||
func (c *systemClient) getDnsClients() ([]dnsClient, error) {
|
||||
return systemResolver, nil
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
//go:build !(android && cmfa)
|
||||
|
||||
package dns
|
||||
|
||||
func UpdateIsolateHandler(resolver *Resolver, mapper *ResolverEnhancer) {
|
||||
}
|
@ -29,6 +29,7 @@ type dnsClient interface {
|
||||
type dnsCache interface {
|
||||
GetWithExpire(key string) (*D.Msg, time.Time, bool)
|
||||
SetWithExpire(key string, value *D.Msg, expire time.Time)
|
||||
Clear()
|
||||
}
|
||||
|
||||
type result struct {
|
||||
@ -369,6 +370,12 @@ func (r *Resolver) Invalid() bool {
|
||||
return len(r.main) > 0
|
||||
}
|
||||
|
||||
func (r *Resolver) ClearCache() {
|
||||
if r != nil && r.cache != nil {
|
||||
r.cache.Clear()
|
||||
}
|
||||
}
|
||||
|
||||
type NameServer struct {
|
||||
Net string
|
||||
Addr string
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/metacubex/mihomo/common/sockopt"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
"github.com/metacubex/mihomo/context"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
@ -50,10 +49,6 @@ func (s *Server) SetHandler(handler handler) {
|
||||
}
|
||||
|
||||
func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) {
|
||||
if features.CMFA {
|
||||
UpdateIsolateHandler(resolver, mapper)
|
||||
}
|
||||
|
||||
if addr == address && resolver != nil {
|
||||
handler := NewHandler(resolver, mapper)
|
||||
server.SetHandler(handler)
|
||||
|
@ -3,16 +3,11 @@ package dns
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
D "github.com/miekg/dns"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -31,64 +26,6 @@ type systemClient struct {
|
||||
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) {
|
||||
dnsClients, err := c.getDnsClients()
|
||||
if err != nil {
|
||||
|
71
dns/system_common.go
Normal file
71
dns/system_common.go
Normal 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
|
||||
}
|
@ -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))
|
||||
continue
|
||||
case "dhcp":
|
||||
if s.Addr == "system" { // Compatible with old writing
|
||||
ret = append(ret, newSystemClient())
|
||||
continue
|
||||
}
|
||||
ret = append(ret, newDHCPClient(s.Addr))
|
||||
continue
|
||||
case "system":
|
||||
|
@ -1,10 +1,7 @@
|
||||
package hub
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/metacubex/mihomo/config"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
"github.com/metacubex/mihomo/hub/executor"
|
||||
"github.com/metacubex/mihomo/hub/route"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
@ -43,11 +40,6 @@ func ApplyConfig(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 != "" {
|
||||
route.SetUIPath(cfg.Controller.ExternalUI)
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"github.com/metacubex/mihomo/common/structure"
|
||||
"github.com/metacubex/mihomo/component/resource"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
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)
|
||||
if 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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user