Feature: add fake-ip-filter

This commit is contained in:
Dreamacro 2019-12-28 00:10:06 +08:00
parent 37603735bd
commit 96f490f84a
4 changed files with 31 additions and 2 deletions

View file

@ -130,6 +130,9 @@ experimental:
# listen: 0.0.0.0:53
# enhanced-mode: redir-host # or fake-ip
# # fake-ip-range: 198.18.0.1/16 # if you don't know what it is, don't change it
# fake-ip-filter: # fake ip white domain list
# - *.lan
# - localhost.ptlogin2.qq.com
# nameserver:
# - 114.114.114.114
# - tls://dns.rubyfish.cn:853 # dns over tls

View file

@ -6,6 +6,7 @@ import (
"sync"
"github.com/Dreamacro/clash/common/cache"
trie "github.com/Dreamacro/clash/component/domain-trie"
)
// Pool is a implementation about fake ip generator without storage
@ -15,6 +16,7 @@ type Pool struct {
gateway uint32
offset uint32
mux sync.Mutex
host *trie.Trie
cache *cache.LruCache
}
@ -60,6 +62,14 @@ func (p *Pool) LookBack(ip net.IP) (string, bool) {
return "", false
}
// LookupHost return if host in host
func (p *Pool) LookupHost(host string) bool {
if p.host == nil {
return false
}
return p.host.Search(host) != nil
}
// Gateway return gateway ip
func (p *Pool) Gateway() net.IP {
return uintToIP(p.gateway)
@ -96,7 +106,7 @@ func uintToIP(v uint32) net.IP {
}
// New return Pool instance
func New(ipnet *net.IPNet, size int) (*Pool, error) {
func New(ipnet *net.IPNet, size int, host *trie.Trie) (*Pool, error) {
min := ipToUint(ipnet.IP) + 2
ones, bits := ipnet.Mask.Size()
@ -111,6 +121,7 @@ func New(ipnet *net.IPNet, size int) (*Pool, error) {
min: min,
max: max,
gateway: min - 1,
host: host,
cache: cache.NewLRUCache(cache.WithSize(size * 2)),
}, nil
}

View file

@ -81,6 +81,7 @@ type rawDNS struct {
Listen string `yaml:"listen"`
EnhancedMode dns.EnhancedMode `yaml:"enhanced-mode"`
FakeIPRange string `yaml:"fake-ip-range"`
FakeIPFilter []string `yaml:"fake-ip-filter"`
}
type rawFallbackFilter struct {
@ -523,7 +524,17 @@ func parseDNS(cfg rawDNS) (*DNS, error) {
if err != nil {
return nil, err
}
pool, err := fakeip.New(ipnet, 1000)
var host *trie.Trie
// fake ip skip host filter
if len(cfg.FakeIPFilter) != 0 {
host = trie.New()
for _, domain := range cfg.FakeIPFilter {
host.Insert(domain, true)
}
}
pool, err := fakeip.New(ipnet, 1000, host)
if err != nil {
return nil, err
}

View file

@ -26,6 +26,10 @@ func withFakeIP(fakePool *fakeip.Pool) middleware {
}
host := strings.TrimRight(q.Name, ".")
if fakePool.LookupHost(host) {
next(w, r)
return
}
rr := &D.A{}
rr.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL}