Add rule-set

This commit is contained in:
世界
2023-12-01 13:24:12 +08:00
parent 7df151e820
commit 4b43acfec0
51 changed files with 2975 additions and 265 deletions

View File

@@ -1,6 +1,7 @@
package route
import (
"io"
"strings"
"github.com/sagernet/sing-box/adapter"
@@ -16,6 +17,7 @@ type abstractDefaultRule struct {
destinationAddressItems []RuleItem
destinationPortItems []RuleItem
allItems []RuleItem
ruleSetItem RuleItem
invert bool
outbound string
}
@@ -61,62 +63,62 @@ func (r *abstractDefaultRule) Match(metadata *adapter.InboundContext) bool {
return true
}
if len(r.sourceAddressItems) > 0 && !metadata.SourceAddressMatch {
for _, item := range r.sourceAddressItems {
if item.Match(metadata) {
metadata.SourceAddressMatch = true
break
}
}
}
if len(r.sourcePortItems) > 0 && !metadata.SourceAddressMatch {
for _, item := range r.sourcePortItems {
if item.Match(metadata) {
metadata.SourcePortMatch = true
break
}
}
}
if len(r.destinationAddressItems) > 0 && !metadata.SourceAddressMatch {
for _, item := range r.destinationAddressItems {
if item.Match(metadata) {
metadata.DestinationAddressMatch = true
break
}
}
}
if len(r.destinationPortItems) > 0 && !metadata.SourceAddressMatch {
for _, item := range r.destinationPortItems {
if item.Match(metadata) {
metadata.DestinationPortMatch = true
break
}
}
}
for _, item := range r.items {
if !item.Match(metadata) {
return r.invert
}
}
if len(r.sourceAddressItems) > 0 {
var sourceAddressMatch bool
for _, item := range r.sourceAddressItems {
if item.Match(metadata) {
sourceAddressMatch = true
break
}
}
if !sourceAddressMatch {
return r.invert
}
if len(r.sourceAddressItems) > 0 && !metadata.SourceAddressMatch {
return r.invert
}
if len(r.sourcePortItems) > 0 {
var sourcePortMatch bool
for _, item := range r.sourcePortItems {
if item.Match(metadata) {
sourcePortMatch = true
break
}
}
if !sourcePortMatch {
return r.invert
}
if len(r.sourcePortItems) > 0 && !metadata.SourcePortMatch {
return r.invert
}
if len(r.destinationAddressItems) > 0 {
var destinationAddressMatch bool
for _, item := range r.destinationAddressItems {
if item.Match(metadata) {
destinationAddressMatch = true
break
}
}
if !destinationAddressMatch {
return r.invert
}
if len(r.destinationAddressItems) > 0 && !metadata.DestinationAddressMatch {
return r.invert
}
if len(r.destinationPortItems) > 0 {
var destinationPortMatch bool
for _, item := range r.destinationPortItems {
if item.Match(metadata) {
destinationPortMatch = true
break
}
}
if !destinationPortMatch {
return r.invert
}
if len(r.destinationPortItems) > 0 && !metadata.DestinationPortMatch {
return r.invert
}
return !r.invert
@@ -135,7 +137,7 @@ func (r *abstractDefaultRule) String() string {
}
type abstractLogicalRule struct {
rules []adapter.Rule
rules []adapter.HeadlessRule
mode string
invert bool
outbound string
@@ -146,7 +148,10 @@ func (r *abstractLogicalRule) Type() string {
}
func (r *abstractLogicalRule) UpdateGeosite() error {
for _, rule := range r.rules {
for _, rule := range common.FilterIsInstance(r.rules, func(it adapter.HeadlessRule) (adapter.Rule, bool) {
rule, loaded := it.(adapter.Rule)
return rule, loaded
}) {
err := rule.UpdateGeosite()
if err != nil {
return err
@@ -156,7 +161,10 @@ func (r *abstractLogicalRule) UpdateGeosite() error {
}
func (r *abstractLogicalRule) Start() error {
for _, rule := range r.rules {
for _, rule := range common.FilterIsInstance(r.rules, func(it adapter.HeadlessRule) (common.Starter, bool) {
rule, loaded := it.(common.Starter)
return rule, loaded
}) {
err := rule.Start()
if err != nil {
return err
@@ -166,7 +174,10 @@ func (r *abstractLogicalRule) Start() error {
}
func (r *abstractLogicalRule) Close() error {
for _, rule := range r.rules {
for _, rule := range common.FilterIsInstance(r.rules, func(it adapter.HeadlessRule) (io.Closer, bool) {
rule, loaded := it.(io.Closer)
return rule, loaded
}) {
err := rule.Close()
if err != nil {
return err
@@ -177,11 +188,13 @@ func (r *abstractLogicalRule) Close() error {
func (r *abstractLogicalRule) Match(metadata *adapter.InboundContext) bool {
if r.mode == C.LogicalTypeAnd {
return common.All(r.rules, func(it adapter.Rule) bool {
return common.All(r.rules, func(it adapter.HeadlessRule) bool {
metadata.ResetRuleCache()
return it.Match(metadata)
}) != r.invert
} else {
return common.Any(r.rules, func(it adapter.Rule) bool {
return common.Any(r.rules, func(it adapter.HeadlessRule) bool {
metadata.ResetRuleCache()
return it.Match(metadata)
}) != r.invert
}