Explorar o código

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

Closes https://github.com/XTLS/Xray-core/issues/5429
Meow hai 5 meses
pai
achega
7f6ceb39f7
Modificáronse 5 ficheiros con 19 adicións e 13 borrados
  1. 1 2
      app/dns/dns.go
  2. 7 2
      app/dns/hosts.go
  3. 4 6
      app/dns/nameserver.go
  4. 5 2
      app/router/condition.go
  5. 2 1
      common/strmatcher/strmatcher.go

+ 1 - 2
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

+ 7 - 2
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

+ 4 - 6
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

+ 5 - 2
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()

+ 2 - 1
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")
 	}
 }