github.com/kelleygo/clashcore@v1.0.2/dns/enhancer.go (about)

     1  package dns
     2  
     3  import (
     4  	"net/netip"
     5  
     6  	"github.com/kelleygo/clashcore/common/lru"
     7  	"github.com/kelleygo/clashcore/component/fakeip"
     8  	C "github.com/kelleygo/clashcore/constant"
     9  )
    10  
    11  type ResolverEnhancer struct {
    12  	mode     C.DNSMode
    13  	fakePool *fakeip.Pool
    14  	mapping  *lru.LruCache[netip.Addr, string]
    15  }
    16  
    17  func (h *ResolverEnhancer) FakeIPEnabled() bool {
    18  	return h.mode == C.DNSFakeIP
    19  }
    20  
    21  func (h *ResolverEnhancer) MappingEnabled() bool {
    22  	return h.mode == C.DNSFakeIP || h.mode == C.DNSMapping
    23  }
    24  
    25  func (h *ResolverEnhancer) IsExistFakeIP(ip netip.Addr) bool {
    26  	if !h.FakeIPEnabled() {
    27  		return false
    28  	}
    29  
    30  	if pool := h.fakePool; pool != nil {
    31  		return pool.Exist(ip)
    32  	}
    33  
    34  	return false
    35  }
    36  
    37  func (h *ResolverEnhancer) IsFakeIP(ip netip.Addr) bool {
    38  	if !h.FakeIPEnabled() {
    39  		return false
    40  	}
    41  
    42  	if pool := h.fakePool; pool != nil {
    43  		return pool.IPNet().Contains(ip) && ip != pool.Gateway() && ip != pool.Broadcast()
    44  	}
    45  
    46  	return false
    47  }
    48  
    49  func (h *ResolverEnhancer) IsFakeBroadcastIP(ip netip.Addr) bool {
    50  	if !h.FakeIPEnabled() {
    51  		return false
    52  	}
    53  
    54  	if pool := h.fakePool; pool != nil {
    55  		return pool.Broadcast() == ip
    56  	}
    57  
    58  	return false
    59  }
    60  
    61  func (h *ResolverEnhancer) FindHostByIP(ip netip.Addr) (string, bool) {
    62  	if pool := h.fakePool; pool != nil {
    63  		if host, existed := pool.LookBack(ip); existed {
    64  			return host, true
    65  		}
    66  	}
    67  
    68  	if mapping := h.mapping; mapping != nil {
    69  		if host, existed := h.mapping.Get(ip); existed {
    70  			return host, true
    71  		}
    72  	}
    73  
    74  	return "", false
    75  }
    76  
    77  func (h *ResolverEnhancer) InsertHostByIP(ip netip.Addr, host string) {
    78  	if mapping := h.mapping; mapping != nil {
    79  		h.mapping.Set(ip, host)
    80  	}
    81  }
    82  
    83  func (h *ResolverEnhancer) FlushFakeIP() error {
    84  	if h.fakePool != nil {
    85  		return h.fakePool.FlushFakeIP()
    86  	}
    87  	return nil
    88  }
    89  
    90  func (h *ResolverEnhancer) PatchFrom(o *ResolverEnhancer) {
    91  	if h.mapping != nil && o.mapping != nil {
    92  		o.mapping.CloneTo(h.mapping)
    93  	}
    94  
    95  	if h.fakePool != nil && o.fakePool != nil {
    96  		h.fakePool.CloneFrom(o.fakePool)
    97  	}
    98  }
    99  
   100  func (h *ResolverEnhancer) StoreFakePoolState() {
   101  	if h.fakePool != nil {
   102  		h.fakePool.StoreState()
   103  	}
   104  }
   105  
   106  func NewEnhancer(cfg Config) *ResolverEnhancer {
   107  	var fakePool *fakeip.Pool
   108  	var mapping *lru.LruCache[netip.Addr, string]
   109  
   110  	if cfg.EnhancedMode != C.DNSNormal {
   111  		fakePool = cfg.Pool
   112  		mapping = lru.New(lru.WithSize[netip.Addr, string](4096))
   113  	}
   114  
   115  	return &ResolverEnhancer{
   116  		mode:     cfg.EnhancedMode,
   117  		fakePool: fakePool,
   118  		mapping:  mapping,
   119  	}
   120  }