From 7f6ceb39f7f1bae9910b952df4ca932c5a00d40c Mon Sep 17 00:00:00 2001 From: Meow <197331664+Meo597@users.noreply.github.com> Date: Tue, 23 Dec 2025 18:14:42 +0800 Subject: [PATCH] DomainMatcher: Prevent illegal domain rules from causing core startup failures (#5430) Closes https://github.com/XTLS/Xray-core/issues/5429 --- app/dns/dns.go | 3 +-- app/dns/hosts.go | 9 +++++++-- app/dns/nameserver.go | 10 ++++------ app/router/condition.go | 7 +++++-- common/strmatcher/strmatcher.go | 3 ++- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/dns/dns.go b/app/dns/dns.go index 79f9e8e1..603640f1 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -106,13 +106,12 @@ func New(ctx context.Context, config *Config) (*DNS, error) { for _, ns := range config.NameServer { clientIdx := len(clients) - updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int, matcherInfos []*DomainMatcherInfo) error { + updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int, matcherInfos []*DomainMatcherInfo) { midx := domainMatcher.Add(domainRule) matcherInfos[midx] = &DomainMatcherInfo{ clientIdx: uint16(clientIdx), domainRuleIdx: uint16(originalRuleIdx), } - return nil } myClientIP := clientIP diff --git a/app/dns/hosts.go b/app/dns/hosts.go index c2f7649d..0ee4fdd0 100644 --- a/app/dns/hosts.go +++ b/app/dns/hosts.go @@ -27,7 +27,8 @@ func NewStaticHosts(hosts []*Config_HostMapping) (*StaticHosts, error) { for _, mapping := range hosts { matcher, err := toStrMatcher(mapping.Type, mapping.Domain) if err != nil { - return nil, errors.New("failed to create domain matcher").Base(err) + errors.LogErrorInner(context.Background(), err, "failed to create domain matcher, ignore domain rule [type: ", mapping.Type, ", domain: ", mapping.Domain, "]") + continue } id := g.Add(matcher) ips := make([]net.Address, 0, len(mapping.Ip)+1) @@ -46,10 +47,14 @@ func NewStaticHosts(hosts []*Config_HostMapping) (*StaticHosts, error) { for _, ip := range mapping.Ip { addr := net.IPAddress(ip) if addr == nil { - return nil, errors.New("invalid IP address in static hosts: ", ip).AtWarning() + errors.LogError(context.Background(), "invalid IP address in static hosts: ", ip, ", ignore this ip for rule [type: ", mapping.Type, ", domain: ", mapping.Domain, "]") + continue } ips = append(ips, addr) } + if len(ips) == 0 { + continue + } } sh.ips[id] = ips diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index e606d4b3..bad9277c 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -97,7 +97,7 @@ func NewClient( tag string, ipOption dns.IPOption, matcherInfos *[]*DomainMatcherInfo, - updateDomainRule func(strmatcher.Matcher, int, []*DomainMatcherInfo) error, + updateDomainRule func(strmatcher.Matcher, int, []*DomainMatcherInfo), ) (*Client, error) { client := &Client{} @@ -134,7 +134,8 @@ func NewClient( for _, domain := range ns.PrioritizedDomain { domainRule, err := toStrMatcher(domain.Type, domain.Domain) if err != nil { - return errors.New("failed to create prioritized domain").Base(err).AtWarning() + errors.LogErrorInner(ctx, err, "failed to create domain matcher, ignore domain rule [type: ", domain.Type, ", domain: ", domain.Domain, "]") + domainRule, _ = toStrMatcher(DomainMatchingType_Full, "hack.fix.index.for.illegal.domain.rule") } originalRuleIdx := ruleCurr if ruleCurr < len(ns.OriginalRules) { @@ -151,10 +152,7 @@ func NewClient( rules = append(rules, domainRule.String()) ruleCurr++ } - err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos) - if err != nil { - return errors.New("failed to create prioritized domain").Base(err).AtWarning() - } + updateDomainRule(domainRule, originalRuleIdx, *matcherInfos) } // Establish expected IPs diff --git a/app/router/condition.go b/app/router/condition.go index 083cbfaf..d21487a2 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -1,6 +1,7 @@ package router import ( + "context" "regexp" "strings" @@ -56,11 +57,13 @@ func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) { for _, d := range domains { matcherType, f := matcherTypeMap[d.Type] if !f { - return nil, errors.New("unsupported domain type", d.Type) + errors.LogError(context.Background(), "ignore unsupported domain type ", d.Type, " of rule ", d.Value) + continue } _, err := g.AddPattern(d.Value, matcherType) if err != nil { - return nil, err + errors.LogErrorInner(context.Background(), err, "ignore domain rule ", d.Type, " ", d.Value) + continue } } g.Build() diff --git a/common/strmatcher/strmatcher.go b/common/strmatcher/strmatcher.go index 294e6e73..4035acc3 100644 --- a/common/strmatcher/strmatcher.go +++ b/common/strmatcher/strmatcher.go @@ -1,6 +1,7 @@ package strmatcher import ( + "errors" "regexp" ) @@ -44,7 +45,7 @@ func (t Type) New(pattern string) (Matcher, error) { pattern: r, }, nil default: - panic("Unknown type") + return nil, errors.New("unk type") } }