mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 20:52:15 +08:00
feat: add fake-ip-filter-mode
in dns
https://github.com/MetaCubeX/mihomo/issues/1479
This commit is contained in:
parent
08ac9a3fae
commit
f6164ac195
@ -36,6 +36,7 @@ type Pool struct {
|
|||||||
cycle bool
|
cycle bool
|
||||||
mux sync.Mutex
|
mux sync.Mutex
|
||||||
host []C.DomainMatcher
|
host []C.DomainMatcher
|
||||||
|
mode C.FilterMode
|
||||||
ipnet netip.Prefix
|
ipnet netip.Prefix
|
||||||
store store
|
store store
|
||||||
}
|
}
|
||||||
@ -66,6 +67,14 @@ func (p *Pool) LookBack(ip netip.Addr) (string, bool) {
|
|||||||
|
|
||||||
// ShouldSkipped return if domain should be skipped
|
// ShouldSkipped return if domain should be skipped
|
||||||
func (p *Pool) ShouldSkipped(domain string) bool {
|
func (p *Pool) ShouldSkipped(domain string) bool {
|
||||||
|
should := p.shouldSkipped(domain)
|
||||||
|
if p.mode == C.FilterWhiteList {
|
||||||
|
return !should
|
||||||
|
}
|
||||||
|
return should
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pool) shouldSkipped(domain string) bool {
|
||||||
for _, matcher := range p.host {
|
for _, matcher := range p.host {
|
||||||
if matcher.MatchDomain(domain) {
|
if matcher.MatchDomain(domain) {
|
||||||
return true
|
return true
|
||||||
@ -157,6 +166,7 @@ func (p *Pool) restoreState() {
|
|||||||
type Options struct {
|
type Options struct {
|
||||||
IPNet netip.Prefix
|
IPNet netip.Prefix
|
||||||
Host []C.DomainMatcher
|
Host []C.DomainMatcher
|
||||||
|
Mode C.FilterMode
|
||||||
|
|
||||||
// Size sets the maximum number of entries in memory
|
// Size sets the maximum number of entries in memory
|
||||||
// and does not work if Persistence is true
|
// and does not work if Persistence is true
|
||||||
@ -187,6 +197,7 @@ func New(options Options) (*Pool, error) {
|
|||||||
offset: first.Prev(),
|
offset: first.Prev(),
|
||||||
cycle: false,
|
cycle: false,
|
||||||
host: options.Host,
|
host: options.Host,
|
||||||
|
mode: options.Mode,
|
||||||
ipnet: options.IPNet,
|
ipnet: options.IPNet,
|
||||||
}
|
}
|
||||||
if options.Persistence {
|
if options.Persistence {
|
||||||
|
@ -164,6 +164,28 @@ func TestPool_Skip(t *testing.T) {
|
|||||||
for _, pool := range pools {
|
for _, pool := range pools {
|
||||||
assert.True(t, pool.ShouldSkipped("example.com"))
|
assert.True(t, pool.ShouldSkipped("example.com"))
|
||||||
assert.False(t, pool.ShouldSkipped("foo.com"))
|
assert.False(t, pool.ShouldSkipped("foo.com"))
|
||||||
|
assert.False(t, pool.shouldSkipped("baz.com"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPool_SkipWhiteList(t *testing.T) {
|
||||||
|
ipnet := netip.MustParsePrefix("192.168.0.1/29")
|
||||||
|
tree := trie.New[struct{}]()
|
||||||
|
assert.NoError(t, tree.Insert("example.com", struct{}{}))
|
||||||
|
assert.False(t, tree.IsEmpty())
|
||||||
|
pools, tempfile, err := createPools(Options{
|
||||||
|
IPNet: ipnet,
|
||||||
|
Size: 10,
|
||||||
|
Host: []C.DomainMatcher{tree.NewDomainSet()},
|
||||||
|
Mode: C.FilterWhiteList,
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
defer os.Remove(tempfile)
|
||||||
|
|
||||||
|
for _, pool := range pools {
|
||||||
|
assert.False(t, pool.ShouldSkipped("example.com"))
|
||||||
|
assert.True(t, pool.ShouldSkipped("foo.com"))
|
||||||
|
assert.True(t, pool.ShouldSkipped("baz.com"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +205,7 @@ type RawDNS struct {
|
|||||||
EnhancedMode C.DNSMode `yaml:"enhanced-mode" json:"enhanced-mode"`
|
EnhancedMode C.DNSMode `yaml:"enhanced-mode" json:"enhanced-mode"`
|
||||||
FakeIPRange string `yaml:"fake-ip-range" json:"fake-ip-range"`
|
FakeIPRange string `yaml:"fake-ip-range" json:"fake-ip-range"`
|
||||||
FakeIPFilter []string `yaml:"fake-ip-filter" json:"fake-ip-filter"`
|
FakeIPFilter []string `yaml:"fake-ip-filter" json:"fake-ip-filter"`
|
||||||
|
FakeIPFilterMode C.FilterMode `yaml:"fake-ip-filter-mode" json:"fake-ip-filter-mode"`
|
||||||
DefaultNameserver []string `yaml:"default-nameserver" json:"default-nameserver"`
|
DefaultNameserver []string `yaml:"default-nameserver" json:"default-nameserver"`
|
||||||
CacheAlgorithm string `yaml:"cache-algorithm" json:"cache-algorithm"`
|
CacheAlgorithm string `yaml:"cache-algorithm" json:"cache-algorithm"`
|
||||||
NameServerPolicy *orderedmap.OrderedMap[string, any] `yaml:"nameserver-policy" json:"nameserver-policy"`
|
NameServerPolicy *orderedmap.OrderedMap[string, any] `yaml:"nameserver-policy" json:"nameserver-policy"`
|
||||||
@ -474,6 +475,7 @@ func DefaultRawConfig() *RawConfig {
|
|||||||
"www.msftnsci.com",
|
"www.msftnsci.com",
|
||||||
"www.msftconnecttest.com",
|
"www.msftconnecttest.com",
|
||||||
},
|
},
|
||||||
|
FakeIPFilterMode: C.FilterBlackList,
|
||||||
},
|
},
|
||||||
NTP: RawNTP{
|
NTP: RawNTP{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
@ -1458,6 +1460,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
|||||||
IPNet: fakeIPRange,
|
IPNet: fakeIPRange,
|
||||||
Size: 1000,
|
Size: 1000,
|
||||||
Host: host,
|
Host: host,
|
||||||
|
Mode: cfg.FakeIPFilterMode,
|
||||||
Persistence: rawCfg.Profile.StoreFakeIP,
|
Persistence: rawCfg.Profile.StoreFakeIP,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -43,7 +43,9 @@ func (e DNSMode) MarshalYAML() (any, error) {
|
|||||||
// UnmarshalJSON unserialize EnhancedMode with json
|
// UnmarshalJSON unserialize EnhancedMode with json
|
||||||
func (e *DNSMode) UnmarshalJSON(data []byte) error {
|
func (e *DNSMode) UnmarshalJSON(data []byte) error {
|
||||||
var tp string
|
var tp string
|
||||||
json.Unmarshal(data, &tp)
|
if err := json.Unmarshal(data, &tp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
mode, exist := DNSModeMapping[tp]
|
mode, exist := DNSModeMapping[tp]
|
||||||
if !exist {
|
if !exist {
|
||||||
return errors.New("invalid mode")
|
return errors.New("invalid mode")
|
||||||
@ -115,6 +117,64 @@ func NewDNSPrefer(prefer string) DNSPrefer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterModeMapping is a mapping for FilterMode enum
|
||||||
|
var FilterModeMapping = map[string]FilterMode{
|
||||||
|
FilterBlackList.String(): FilterBlackList,
|
||||||
|
FilterWhiteList.String(): FilterWhiteList,
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
FilterBlackList FilterMode = iota
|
||||||
|
FilterWhiteList
|
||||||
|
)
|
||||||
|
|
||||||
|
func (e FilterMode) String() string {
|
||||||
|
switch e {
|
||||||
|
case FilterBlackList:
|
||||||
|
return "blacklist"
|
||||||
|
case FilterWhiteList:
|
||||||
|
return "whitelist"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e FilterMode) MarshalYAML() (interface{}, error) {
|
||||||
|
return e.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *FilterMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
|
var tp string
|
||||||
|
if err := unmarshal(&tp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mode, exist := FilterModeMapping[tp]
|
||||||
|
if !exist {
|
||||||
|
return errors.New("invalid mode")
|
||||||
|
}
|
||||||
|
*e = mode
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e FilterMode) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(e.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *FilterMode) UnmarshalJSON(data []byte) error {
|
||||||
|
var tp string
|
||||||
|
if err := json.Unmarshal(data, &tp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mode, exist := FilterModeMapping[tp]
|
||||||
|
if !exist {
|
||||||
|
return errors.New("invalid mode")
|
||||||
|
}
|
||||||
|
*e = mode
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type HTTPVersion string
|
type HTTPVersion string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -249,6 +249,9 @@ dns:
|
|||||||
- rule-set:fakeip-filter
|
- rule-set:fakeip-filter
|
||||||
# fakeip-filter 为 geosite 中名为 fakeip-filter 的分类(需要自行保证该分类存在)
|
# fakeip-filter 为 geosite 中名为 fakeip-filter 的分类(需要自行保证该分类存在)
|
||||||
- geosite:fakeip-filter
|
- geosite:fakeip-filter
|
||||||
|
# 配置fake-ip-filter的匹配模式,默认为blacklist,即如果匹配成功不返回fake-ip
|
||||||
|
# 可设置为whitelist,即只有匹配成功才返回fake-ip
|
||||||
|
fake-ip-filter-mode: blacklist
|
||||||
|
|
||||||
# use-hosts: true # 查询 hosts
|
# use-hosts: true # 查询 hosts
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user