Allow nested logical rules

This commit is contained in:
世界
2023-11-28 23:47:32 +08:00
parent 29e688443f
commit ce99c4a709
7 changed files with 79 additions and 47 deletions

View File

@@ -128,14 +128,14 @@ func NewRouter(
Logger: router.dnsLogger,
})
for i, ruleOptions := range options.Rules {
routeRule, err := NewRule(router, router.logger, ruleOptions)
routeRule, err := NewRule(router, router.logger, ruleOptions, true)
if err != nil {
return nil, E.Cause(err, "parse rule[", i, "]")
}
router.rules = append(router.rules, routeRule)
}
for i, dnsRuleOptions := range dnsOptions.Rules {
dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions)
dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions, true)
if err != nil {
return nil, E.Cause(err, "parse dns rule[", i, "]")
}

View File

@@ -252,10 +252,8 @@ func hasRule(rules []option.Rule, cond func(rule option.DefaultRule) bool) bool
return true
}
case C.RuleTypeLogical:
for _, subRule := range rule.LogicalOptions.Rules {
if cond(subRule) {
return true
}
if hasRule(rule.LogicalOptions.Rules, cond) {
return true
}
}
}
@@ -270,10 +268,8 @@ func hasDNSRule(rules []option.DNSRule, cond func(rule option.DefaultDNSRule) bo
return true
}
case C.RuleTypeLogical:
for _, subRule := range rule.LogicalOptions.Rules {
if cond(subRule) {
return true
}
if hasDNSRule(rule.LogicalOptions.Rules, cond) {
return true
}
}
}

View File

@@ -8,13 +8,13 @@ import (
E "github.com/sagernet/sing/common/exceptions"
)
func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rule) (adapter.Rule, error) {
func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rule, checkOutbound bool) (adapter.Rule, error) {
switch options.Type {
case "", C.RuleTypeDefault:
if !options.DefaultOptions.IsValid() {
return nil, E.New("missing conditions")
}
if options.DefaultOptions.Outbound == "" {
if options.DefaultOptions.Outbound == "" && checkOutbound {
return nil, E.New("missing outbound field")
}
return NewDefaultRule(router, logger, options.DefaultOptions)
@@ -22,7 +22,7 @@ func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rul
if !options.LogicalOptions.IsValid() {
return nil, E.New("missing conditions")
}
if options.LogicalOptions.Outbound == "" {
if options.LogicalOptions.Outbound == "" && checkOutbound {
return nil, E.New("missing outbound field")
}
return NewLogicalRule(router, logger, options.LogicalOptions)
@@ -220,7 +220,7 @@ func NewLogicalRule(router adapter.Router, logger log.ContextLogger, options opt
return nil, E.New("unknown logical mode: ", options.Mode)
}
for i, subRule := range options.Rules {
rule, err := NewDefaultRule(router, logger, subRule)
rule, err := NewRule(router, logger, subRule, false)
if err != nil {
return nil, E.Cause(err, "sub rule[", i, "]")
}

View File

@@ -8,13 +8,13 @@ import (
E "github.com/sagernet/sing/common/exceptions"
)
func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule) (adapter.DNSRule, error) {
func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule, checkServer bool) (adapter.DNSRule, error) {
switch options.Type {
case "", C.RuleTypeDefault:
if !options.DefaultOptions.IsValid() {
return nil, E.New("missing conditions")
}
if options.DefaultOptions.Server == "" {
if options.DefaultOptions.Server == "" && checkServer {
return nil, E.New("missing server field")
}
return NewDefaultDNSRule(router, logger, options.DefaultOptions)
@@ -22,7 +22,7 @@ func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.
if !options.LogicalOptions.IsValid() {
return nil, E.New("missing conditions")
}
if options.LogicalOptions.Server == "" {
if options.LogicalOptions.Server == "" && checkServer {
return nil, E.New("missing server field")
}
return NewLogicalDNSRule(router, logger, options.LogicalOptions)
@@ -228,7 +228,7 @@ func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options
return nil, E.New("unknown logical mode: ", options.Mode)
}
for i, subRule := range options.Rules {
rule, err := NewDefaultDNSRule(router, logger, subRule)
rule, err := NewDNSRule(router, logger, subRule, false)
if err != nil {
return nil, E.Cause(err, "sub rule[", i, "]")
}