mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-03-04 04:47:30 +00:00
feat: support ARC for DNS cache
This commit is contained in:
@@ -3,7 +3,7 @@ package dns
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"github.com/metacubex/mihomo/common/cache"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/component/fakeip"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
type ResolverEnhancer struct {
|
||||
mode C.DNSMode
|
||||
fakePool *fakeip.Pool
|
||||
mapping *cache.LruCache[netip.Addr, string]
|
||||
mapping *lru.LruCache[netip.Addr, string]
|
||||
}
|
||||
|
||||
func (h *ResolverEnhancer) FakeIPEnabled() bool {
|
||||
@@ -105,11 +105,11 @@ func (h *ResolverEnhancer) StoreFakePoolState() {
|
||||
|
||||
func NewEnhancer(cfg Config) *ResolverEnhancer {
|
||||
var fakePool *fakeip.Pool
|
||||
var mapping *cache.LruCache[netip.Addr, string]
|
||||
var mapping *lru.LruCache[netip.Addr, string]
|
||||
|
||||
if cfg.EnhancedMode != C.DNSNormal {
|
||||
fakePool = cfg.Pool
|
||||
mapping = cache.New(cache.WithSize[netip.Addr, string](4096))
|
||||
mapping = lru.New(lru.WithSize[netip.Addr, string](4096))
|
||||
}
|
||||
|
||||
return &ResolverEnhancer{
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/cache"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/common/nnip"
|
||||
"github.com/metacubex/mihomo/component/fakeip"
|
||||
R "github.com/metacubex/mihomo/component/resolver"
|
||||
@@ -21,7 +21,7 @@ type (
|
||||
middleware func(next handler) handler
|
||||
)
|
||||
|
||||
func withHosts(hosts R.Hosts, mapping *cache.LruCache[netip.Addr, string]) middleware {
|
||||
func withHosts(hosts R.Hosts, mapping *lru.LruCache[netip.Addr, string]) middleware {
|
||||
return func(next handler) handler {
|
||||
return func(ctx *context.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
q := r.Question[0]
|
||||
@@ -98,7 +98,7 @@ func withHosts(hosts R.Hosts, mapping *cache.LruCache[netip.Addr, string]) middl
|
||||
}
|
||||
}
|
||||
|
||||
func withMapping(mapping *cache.LruCache[netip.Addr, string]) middleware {
|
||||
func withMapping(mapping *lru.LruCache[netip.Addr, string]) middleware {
|
||||
return func(next handler) handler {
|
||||
return func(ctx *context.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
q := r.Question[0]
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
D "github.com/miekg/dns"
|
||||
|
||||
"github.com/metacubex/mihomo/common/cache"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/component/dhcp"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
)
|
||||
@@ -49,7 +49,7 @@ func ServeDNSWithDefaultServer(msg *D.Msg) (*D.Msg, error) {
|
||||
|
||||
func FlushCacheWithDefaultResolver() {
|
||||
if r := resolver.DefaultResolver; r != nil {
|
||||
r.(*Resolver).lruCache = cache.New[string, *D.Msg](cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true))
|
||||
r.(*Resolver).lruCache = lru.New[string, *D.Msg](lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/cache"
|
||||
"github.com/metacubex/mihomo/common/arc"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/component/fakeip"
|
||||
"github.com/metacubex/mihomo/component/geodata/router"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
@@ -28,6 +29,11 @@ type dnsClient interface {
|
||||
Address() string
|
||||
}
|
||||
|
||||
type dnsCache interface {
|
||||
GetWithExpire(key string) (*D.Msg, time.Time, bool)
|
||||
SetWithExpire(key string, value *D.Msg, expire time.Time)
|
||||
}
|
||||
|
||||
type result struct {
|
||||
Msg *D.Msg
|
||||
Error error
|
||||
@@ -42,7 +48,7 @@ type Resolver struct {
|
||||
fallbackDomainFilters []fallbackDomainFilter
|
||||
fallbackIPFilters []fallbackIPFilter
|
||||
group singleflight.Group
|
||||
lruCache *cache.LruCache[string, *D.Msg]
|
||||
cache dnsCache
|
||||
policy []dnsPolicy
|
||||
proxyServer []dnsClient
|
||||
}
|
||||
@@ -140,8 +146,9 @@ func (r *Resolver) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, e
|
||||
}()
|
||||
|
||||
q := m.Question[0]
|
||||
cacheM, expireTime, hit := r.lruCache.GetWithExpire(q.String())
|
||||
cacheM, expireTime, hit := r.cache.GetWithExpire(q.String())
|
||||
if hit {
|
||||
log.Debugln("[DNS] cache hit for %s, expire at %s", q.Name, expireTime.Format("2006-01-02 15:04:05"))
|
||||
now := time.Now()
|
||||
msg = cacheM.Copy()
|
||||
if expireTime.Before(now) {
|
||||
@@ -181,7 +188,7 @@ func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.M
|
||||
msg.Extra = lo.Filter(msg.Extra, func(rr D.RR, index int) bool {
|
||||
return rr.Header().Rrtype != D.TypeOPT
|
||||
})
|
||||
putMsgToCache(r.lruCache, q.String(), q, msg)
|
||||
putMsgToCache(r.cache, q.String(), q, msg)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -408,12 +415,19 @@ type Config struct {
|
||||
Hosts *trie.DomainTrie[resolver.HostValue]
|
||||
Policy *orderedmap.OrderedMap[string, []NameServer]
|
||||
RuleProviders map[string]provider.RuleProvider
|
||||
CacheAlgorithm string
|
||||
}
|
||||
|
||||
func NewResolver(config Config) *Resolver {
|
||||
var cache dnsCache
|
||||
if config.CacheAlgorithm == "lru" {
|
||||
cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true))
|
||||
} else {
|
||||
cache = arc.New(arc.WithSize[string, *D.Msg](4096))
|
||||
}
|
||||
defaultResolver := &Resolver{
|
||||
main: transform(config.Default, nil),
|
||||
lruCache: cache.New(cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)),
|
||||
cache: cache,
|
||||
ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond,
|
||||
}
|
||||
|
||||
@@ -444,10 +458,15 @@ func NewResolver(config Config) *Resolver {
|
||||
return
|
||||
}
|
||||
|
||||
if config.CacheAlgorithm == "" || config.CacheAlgorithm == "lru" {
|
||||
cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true))
|
||||
} else {
|
||||
cache = arc.New(arc.WithSize[string, *D.Msg](4096))
|
||||
}
|
||||
r := &Resolver{
|
||||
ipv6: config.IPv6,
|
||||
main: cacheTransform(config.Main),
|
||||
lruCache: cache.New(cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)),
|
||||
cache: cache,
|
||||
hosts: config.Hosts,
|
||||
ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond,
|
||||
}
|
||||
@@ -550,7 +569,7 @@ func NewProxyServerHostResolver(old *Resolver) *Resolver {
|
||||
r := &Resolver{
|
||||
ipv6: old.ipv6,
|
||||
main: old.proxyServer,
|
||||
lruCache: old.lruCache,
|
||||
cache: old.cache,
|
||||
hosts: old.hosts,
|
||||
ipv6Timeout: old.ipv6Timeout,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/cache"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/nnip"
|
||||
"github.com/metacubex/mihomo/common/picker"
|
||||
@@ -51,7 +50,7 @@ func updateTTL(records []D.RR, ttl uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
func putMsgToCache(c *cache.LruCache[string, *D.Msg], key string, q D.Question, msg *D.Msg) {
|
||||
func putMsgToCache(c dnsCache, key string, q D.Question, msg *D.Msg) {
|
||||
// skip dns cache for acme challenge
|
||||
if q.Qtype == D.TypeTXT && strings.HasPrefix(q.Name, "_acme-challenge.") {
|
||||
log.Debugln("[DNS] dns cache ignored because of acme challenge for: %s", q.Name)
|
||||
|
||||
Reference in New Issue
Block a user