@@ -10,13 +10,27 @@ import (
1010 "github.com/xtls/xray-core/app/router"
1111 "github.com/xtls/xray-core/common/errors"
1212 "github.com/xtls/xray-core/common/net"
13+ "github.com/xtls/xray-core/common/platform"
14+ "github.com/xtls/xray-core/common/platform/filesystem"
1315 "github.com/xtls/xray-core/common/session"
1416 "github.com/xtls/xray-core/common/strmatcher"
1517 "github.com/xtls/xray-core/core"
1618 "github.com/xtls/xray-core/features/dns"
1719 "github.com/xtls/xray-core/features/routing"
1820)
1921
22+ type mphMatcherWrapper struct {
23+ m strmatcher.IndexMatcher
24+ }
25+
26+ func (w * mphMatcherWrapper ) Match (s string ) bool {
27+ return w .m .Match (s ) != nil
28+ }
29+
30+ func (w * mphMatcherWrapper ) String () string {
31+ return "mph-matcher"
32+ }
33+
2034// Server is the interface for Name Server.
2135type Server interface {
2236 // Name of the Client.
@@ -132,29 +146,50 @@ func NewClient(
132146 var rules []string
133147 ruleCurr := 0
134148 ruleIter := 0
135- for i , domain := range ns .PrioritizedDomain {
136- ns .PrioritizedDomain [i ] = nil
137- domainRule , err := toStrMatcher (domain .Type , domain .Domain )
138- if err != nil {
139- errors .LogErrorInner (ctx , err , "failed to create domain matcher, ignore domain rule [type: " , domain .Type , ", domain: " , domain .Domain , "]" )
140- domainRule , _ = toStrMatcher (DomainMatchingType_Full , "hack.fix.index.for.illegal.domain.rule" )
149+
150+ // Check if domain matcher cache is provided via environment
151+ domainMatcherPath := platform .NewEnvFlag (platform .MphCachePath ).GetValue (func () string { return "" })
152+ var mphLoaded bool
153+
154+ if domainMatcherPath != "" && ns .Tag != "" {
155+ f , err := filesystem .NewFileReader (domainMatcherPath )
156+ if err == nil {
157+ defer f .Close ()
158+ g , err := router .LoadGeoSiteMatcher (f , ns .Tag )
159+ if err == nil {
160+ errors .LogDebug (ctx , "MphDomainMatcher loaded from cache for " , ns .Tag , " dns tag)" )
161+ updateDomainRule (& mphMatcherWrapper {m : g }, 0 , * matcherInfos )
162+ rules = append (rules , "[MPH Cache]" )
163+ mphLoaded = true
164+ }
141165 }
142- originalRuleIdx := ruleCurr
143- if ruleCurr < len (ns .OriginalRules ) {
144- rule := ns .OriginalRules [ruleCurr ]
145- if ruleCurr >= len (rules ) {
146- rules = append (rules , rule .Rule )
166+ }
167+
168+ if ! mphLoaded {
169+ for i , domain := range ns .PrioritizedDomain {
170+ ns .PrioritizedDomain [i ] = nil
171+ domainRule , err := toStrMatcher (domain .Type , domain .Domain )
172+ if err != nil {
173+ errors .LogErrorInner (ctx , err , "failed to create domain matcher, ignore domain rule [type: " , domain .Type , ", domain: " , domain .Domain , "]" )
174+ domainRule , _ = toStrMatcher (DomainMatchingType_Full , "hack.fix.index.for.illegal.domain.rule" )
147175 }
148- ruleIter ++
149- if ruleIter >= int (rule .Size ) {
150- ruleIter = 0
176+ originalRuleIdx := ruleCurr
177+ if ruleCurr < len (ns .OriginalRules ) {
178+ rule := ns .OriginalRules [ruleCurr ]
179+ if ruleCurr >= len (rules ) {
180+ rules = append (rules , rule .Rule )
181+ }
182+ ruleIter ++
183+ if ruleIter >= int (rule .Size ) {
184+ ruleIter = 0
185+ ruleCurr ++
186+ }
187+ } else { // No original rule, generate one according to current domain matcher (majorly for compatibility with tests)
188+ rules = append (rules , domainRule .String ())
151189 ruleCurr ++
152190 }
153- } else { // No original rule, generate one according to current domain matcher (majorly for compatibility with tests)
154- rules = append (rules , domainRule .String ())
155- ruleCurr ++
191+ updateDomainRule (domainRule , originalRuleIdx , * matcherInfos )
156192 }
157- updateDomainRule (domainRule , originalRuleIdx , * matcherInfos )
158193 }
159194 ns .PrioritizedDomain = nil
160195 runtime .GC ()
0 commit comments