This commit is contained in:
benyfu911 2023-12-27 18:38:09 +08:00 committed by GitHub
commit 8ac218415e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 12 deletions

View file

@ -9,6 +9,8 @@ import (
"github.com/metacubex/mihomo/common/nnip"
"github.com/metacubex/mihomo/component/profile/cachefile"
"github.com/metacubex/mihomo/component/trie"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log"
)
const (
@ -29,15 +31,16 @@ type store interface {
// Pool is an implementation about fake ip generator without storage
type Pool struct {
gateway netip.Addr
first netip.Addr
last netip.Addr
offset netip.Addr
cycle bool
mux sync.Mutex
host *trie.DomainTrie[struct{}]
ipnet netip.Prefix
store store
gateway netip.Addr
first netip.Addr
last netip.Addr
offset netip.Addr
cycle bool
mux sync.Mutex
host *trie.DomainTrie[struct{}]
ipnet netip.Prefix
store store
FakeipRules []C.Rule
}
// Lookup return a fake ip with host
@ -66,10 +69,20 @@ func (p *Pool) LookBack(ip netip.Addr) (string, bool) {
// ShouldSkipped return if domain should be skipped
func (p *Pool) ShouldSkipped(domain string) bool {
if p.host == nil {
return false
if p.host != nil && p.host.Search(domain) != nil {
return true
}
return p.host.Search(domain) != nil
metadata := C.Metadata{Host: domain}
for _, rule := range p.FakeipRules {
if matched, ada := rule.Match(&metadata); matched {
log.Debugln("`%s` matched fakeip-rules %s", domain, ada)
return ada == "DIRECT"
}
}
return false
}
// Exist returns if given ip exists in fake-ip pool

View file

@ -37,6 +37,7 @@ import (
LC "github.com/metacubex/mihomo/listener/config"
"github.com/metacubex/mihomo/log"
R "github.com/metacubex/mihomo/rules"
RC "github.com/metacubex/mihomo/rules/common"
RP "github.com/metacubex/mihomo/rules/provider"
T "github.com/metacubex/mihomo/tunnel"
@ -180,6 +181,7 @@ type Config struct {
Hosts *trie.DomainTrie[resolver.HostValue]
Profile *Profile
Rules []C.Rule
FakeipRules []C.Rule
SubRules map[string][]C.Rule
Users []auth.AuthUser
Proxies map[string]C.Proxy
@ -336,6 +338,7 @@ type RawConfig struct {
Proxy []map[string]any `yaml:"proxies"`
ProxyGroup []map[string]any `yaml:"proxy-groups"`
Rule []string `yaml:"rules"`
FakeipRules []string `yaml:"fakeip-rules"`
SubRules map[string][]string `yaml:"sub-rules"`
RawTLS TLS `yaml:"tls"`
Listeners []map[string]any `yaml:"listeners"`
@ -558,6 +561,12 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
}
config.Rules = rules
fakeip_rules, err := parseFakeipRules(rawCfg.FakeipRules)
if err != nil {
return nil, err
}
config.FakeipRules = fakeip_rules
hosts, err := parseHosts(rawCfg)
if err != nil {
return nil, err
@ -942,6 +951,66 @@ func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[s
return rules, nil
}
func parseFakeipRules(rulesConfig []string) ([]C.Rule, error) {
var rules []C.Rule
var parsed C.Rule
var parsedErr error
for _, line := range rulesConfig {
rule := trimArr(strings.Split(line, ","))
var (
payload string
target string
ruleName = strings.ToUpper(rule[0])
l = len(rule)
)
if l == 2 {
if ruleName == "MATCH" {
target = rule[1]
} else {
target = "DIRECT"
payload = rule[1]
}
} else if l == 3 {
if ruleName == "MATCH" {
return nil, fmt.Errorf("rule `%s` error: MATCH only accept 1 parameter", line)
} else {
target = rule[2]
payload = rule[1]
}
} else {
return nil, fmt.Errorf("rule `%s` formate error", line)
}
switch ruleName {
case "DOMAIN":
parsed = RC.NewDomain(payload, target)
case "DOMAIN-SUFFIX":
parsed = RC.NewDomainSuffix(payload, target)
case "DOMAIN-KEYWORD":
parsed = RC.NewDomainKeyword(payload, target)
case "RULE-SET":
parsed, parsedErr = RP.NewRuleSet(payload, target, true)
case "GEOSITE":
parsed, parsedErr = RC.NewGEOSITE(payload, target)
case "MATCH":
parsed = RC.NewMatch(target)
parsedErr = nil
default:
parsedErr = fmt.Errorf("unsupported rule type %s", ruleName)
}
if parsedErr != nil {
return nil, parsedErr
}
rules = append(rules, parsed)
}
return rules, nil
}
func parseHosts(cfg *RawConfig) (*trie.DomainTrie[resolver.HostValue], error) {
tree := trie.New[resolver.HostValue]()

View file

@ -98,6 +98,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
updateGeneral(cfg.General)
updateNTP(cfg.NTP)
updateDNS(cfg.DNS, cfg.RuleProviders, cfg.General.IPv6)
cfg.DNS.FakeIPRange.FakeipRules = cfg.FakeipRules
updateListeners(cfg.General, cfg.Listeners, force)
updateIPTables(cfg)
updateTun(cfg.General)