perf(router): adjust the order of rules to optimize performance (#5267)

This commit is contained in:
Meow authored and GitHub committed 2025-11-21 05:30:16 +00:00
1 parent fcfb0a302a
commit 2185a730d2
2 files changed
+28 -42

No files matched your search

-14
View File
@@ -47,20 +47,6 @@ var matcherTypeMap = map[Domain_Type]strmatcher.Type{
Domain_Full: strmatcher.Full, Domain_Full: strmatcher.Full,
} }
func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
matcherType, f := matcherTypeMap[domain.Type]
if !f {
return nil, errors.New("unsupported domain type", domain.Type)
}
matcher, err := matcherType.New(domain.Value)
if err != nil {
return nil, errors.New("failed to create domain matcher").Base(err)
}
return matcher, nil
}
type DomainMatcher struct { type DomainMatcher struct {
matchers strmatcher.IndexMatcher matchers strmatcher.IndexMatcher
} }
+28 -28
View File
@@ -32,27 +32,18 @@ func (r *Rule) Apply(ctx routing.Context) bool {
func (rr *RoutingRule) BuildCondition() (Condition, error) { func (rr *RoutingRule) BuildCondition() (Condition, error) {
conds := NewConditionChan() conds := NewConditionChan()
if len(rr.Domain) > 0 {
matcher, err := NewMphMatcherGroup(rr.Domain)
if err != nil {
return nil, errors.New("failed to build domain condition with MphDomainMatcher").Base(err)
}
errors.LogDebug(context.Background(), "MphDomainMatcher is enabled for ", len(rr.Domain), " domain rule(s)")
conds.Add(matcher)
}
if len(rr.UserEmail) > 0 {
conds.Add(NewUserMatcher(rr.UserEmail))
}
if rr.VlessRouteList != nil {
conds.Add(NewPortMatcher(rr.VlessRouteList, MatcherAsType_VlessRoute))
}
if len(rr.InboundTag) > 0 { if len(rr.InboundTag) > 0 {
conds.Add(NewInboundTagMatcher(rr.InboundTag)) conds.Add(NewInboundTagMatcher(rr.InboundTag))
} }
if len(rr.Networks) > 0 {
conds.Add(NewNetworkMatcher(rr.Networks))
}
if len(rr.Protocol) > 0 {
conds.Add(NewProtocolMatcher(rr.Protocol))
}
if rr.PortList != nil { if rr.PortList != nil {
conds.Add(NewPortMatcher(rr.PortList, MatcherAsType_Target)) conds.Add(NewPortMatcher(rr.PortList, MatcherAsType_Target))
} }
@@ -65,8 +56,20 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
conds.Add(NewPortMatcher(rr.LocalPortList, MatcherAsType_Local)) conds.Add(NewPortMatcher(rr.LocalPortList, MatcherAsType_Local))
} }
if len(rr.Networks) > 0 { if rr.VlessRouteList != nil {
conds.Add(NewNetworkMatcher(rr.Networks)) conds.Add(NewPortMatcher(rr.VlessRouteList, MatcherAsType_VlessRoute))
}
if len(rr.UserEmail) > 0 {
conds.Add(NewUserMatcher(rr.UserEmail))
}
if len(rr.Attributes) > 0 {
configuredKeys := make(map[string]*regexp.Regexp)
for key, value := range rr.Attributes {
configuredKeys[strings.ToLower(key)] = regexp.MustCompile(value)
}
conds.Add(&AttributeMatcher{configuredKeys})
} }
if len(rr.Geoip) > 0 { if len(rr.Geoip) > 0 {
@@ -94,16 +97,13 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
errors.LogWarning(context.Background(), "Due to some limitations, in UDP connections, localIP is always equal to listen interface IP, so \"localIP\" rule condition does not work properly on UDP inbound connections that listen on all interfaces") errors.LogWarning(context.Background(), "Due to some limitations, in UDP connections, localIP is always equal to listen interface IP, so \"localIP\" rule condition does not work properly on UDP inbound connections that listen on all interfaces")
} }
if len(rr.Protocol) > 0 { if len(rr.Domain) > 0 {
conds.Add(NewProtocolMatcher(rr.Protocol)) matcher, err := NewMphMatcherGroup(rr.Domain)
} if err != nil {
return nil, errors.New("failed to build domain condition with MphDomainMatcher").Base(err)
if len(rr.Attributes) > 0 {
configuredKeys := make(map[string]*regexp.Regexp)
for key, value := range rr.Attributes {
configuredKeys[strings.ToLower(key)] = regexp.MustCompile(value)
} }
conds.Add(&AttributeMatcher{configuredKeys}) errors.LogDebug(context.Background(), "MphDomainMatcher is enabled for ", len(rr.Domain), " domain rule(s)")
conds.Add(matcher)
} }
if conds.Len() == 0 { if conds.Len() == 0 {