DomainMatcher: Prevent illegal domain rules from causing core startup failures (#5430)

Closes https://github.com/XTLS/Xray-core/issues/5429
This commit is contained in:
Meow
2025-12-23 18:14:42 +08:00
committed by GitHub
parent fa64775f07
commit 7f6ceb39f7
5 changed files with 19 additions and 13 deletions

View File

@@ -106,13 +106,12 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
for _, ns := range config.NameServer { for _, ns := range config.NameServer {
clientIdx := len(clients) 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) midx := domainMatcher.Add(domainRule)
matcherInfos[midx] = &DomainMatcherInfo{ matcherInfos[midx] = &DomainMatcherInfo{
clientIdx: uint16(clientIdx), clientIdx: uint16(clientIdx),
domainRuleIdx: uint16(originalRuleIdx), domainRuleIdx: uint16(originalRuleIdx),
} }
return nil
} }
myClientIP := clientIP myClientIP := clientIP

View File

@@ -27,7 +27,8 @@ func NewStaticHosts(hosts []*Config_HostMapping) (*StaticHosts, error) {
for _, mapping := range hosts { for _, mapping := range hosts {
matcher, err := toStrMatcher(mapping.Type, mapping.Domain) matcher, err := toStrMatcher(mapping.Type, mapping.Domain)
if err != nil { 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) id := g.Add(matcher)
ips := make([]net.Address, 0, len(mapping.Ip)+1) 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 { for _, ip := range mapping.Ip {
addr := net.IPAddress(ip) addr := net.IPAddress(ip)
if addr == nil { 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) ips = append(ips, addr)
} }
if len(ips) == 0 {
continue
}
} }
sh.ips[id] = ips sh.ips[id] = ips

View File

@@ -97,7 +97,7 @@ func NewClient(
tag string, tag string,
ipOption dns.IPOption, ipOption dns.IPOption,
matcherInfos *[]*DomainMatcherInfo, matcherInfos *[]*DomainMatcherInfo,
updateDomainRule func(strmatcher.Matcher, int, []*DomainMatcherInfo) error, updateDomainRule func(strmatcher.Matcher, int, []*DomainMatcherInfo),
) (*Client, error) { ) (*Client, error) {
client := &Client{} client := &Client{}
@@ -134,7 +134,8 @@ func NewClient(
for _, domain := range ns.PrioritizedDomain { for _, domain := range ns.PrioritizedDomain {
domainRule, err := toStrMatcher(domain.Type, domain.Domain) domainRule, err := toStrMatcher(domain.Type, domain.Domain)
if err != nil { 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 originalRuleIdx := ruleCurr
if ruleCurr < len(ns.OriginalRules) { if ruleCurr < len(ns.OriginalRules) {
@@ -151,10 +152,7 @@ func NewClient(
rules = append(rules, domainRule.String()) rules = append(rules, domainRule.String())
ruleCurr++ ruleCurr++
} }
err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos) updateDomainRule(domainRule, originalRuleIdx, *matcherInfos)
if err != nil {
return errors.New("failed to create prioritized domain").Base(err).AtWarning()
}
} }
// Establish expected IPs // Establish expected IPs

View File

@@ -1,6 +1,7 @@
package router package router
import ( import (
"context"
"regexp" "regexp"
"strings" "strings"
@@ -56,11 +57,13 @@ func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) {
for _, d := range domains { for _, d := range domains {
matcherType, f := matcherTypeMap[d.Type] matcherType, f := matcherTypeMap[d.Type]
if !f { 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) _, err := g.AddPattern(d.Value, matcherType)
if err != nil { if err != nil {
return nil, err errors.LogErrorInner(context.Background(), err, "ignore domain rule ", d.Type, " ", d.Value)
continue
} }
} }
g.Build() g.Build()

View File

@@ -1,6 +1,7 @@
package strmatcher package strmatcher
import ( import (
"errors"
"regexp" "regexp"
) )
@@ -44,7 +45,7 @@ func (t Type) New(pattern string) (Matcher, error) {
pattern: r, pattern: r,
}, nil }, nil
default: default:
panic("Unknown type") return nil, errors.New("unk type")
} }
} }