mirror of
https://github.com/apernet/OpenGFW.git
synced 2024-11-14 22:39:26 +08:00
chore: improve built-in funcs handling (#43)
This commit is contained in:
parent
f8f0153664
commit
6871244809
@ -46,7 +46,6 @@ type compiledExprRule struct {
|
|||||||
Action Action
|
Action Action
|
||||||
ModInstance modifier.Instance
|
ModInstance modifier.Instance
|
||||||
Program *vm.Program
|
Program *vm.Program
|
||||||
Analyzers map[string]struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Ruleset = (*exprRuleset)(nil)
|
var _ Ruleset = (*exprRuleset)(nil)
|
||||||
@ -100,55 +99,45 @@ func CompileExprRules(rules []ExprRule, ans []analyzer.Analyzer, mods []modifier
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("rule %q has invalid action %q", rule.Name, rule.Action)
|
return nil, fmt.Errorf("rule %q has invalid action %q", rule.Name, rule.Action)
|
||||||
}
|
}
|
||||||
visitor := &depVisitor{Analyzers: make(map[string]struct{})}
|
visitor := &idVisitor{Identifiers: make(map[string]bool)}
|
||||||
geoip := expr.Function(
|
|
||||||
"geoip",
|
|
||||||
func(params ...any) (any, error) {
|
|
||||||
return geoMatcher.MatchGeoIp(params[0].(string), params[1].(string)), nil
|
|
||||||
},
|
|
||||||
new(func(string, string) bool),
|
|
||||||
)
|
|
||||||
geosite := expr.Function(
|
|
||||||
"geosite",
|
|
||||||
func(params ...any) (any, error) {
|
|
||||||
return geoMatcher.MatchGeoSite(params[0].(string), params[1].(string)), nil
|
|
||||||
},
|
|
||||||
new(func(string, string) bool),
|
|
||||||
)
|
|
||||||
program, err := expr.Compile(rule.Expr,
|
program, err := expr.Compile(rule.Expr,
|
||||||
func(c *conf.Config) {
|
func(c *conf.Config) {
|
||||||
c.Strict = false
|
c.Strict = false
|
||||||
c.Expect = reflect.Bool
|
c.Expect = reflect.Bool
|
||||||
c.Visitors = append(c.Visitors, visitor)
|
c.Visitors = append(c.Visitors, visitor)
|
||||||
|
registerBuiltinFunctions(c.Functions, geoMatcher)
|
||||||
},
|
},
|
||||||
geoip,
|
|
||||||
geosite,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("rule %q has invalid expression: %w", rule.Name, err)
|
return nil, fmt.Errorf("rule %q has invalid expression: %w", rule.Name, err)
|
||||||
}
|
}
|
||||||
for name := range visitor.Analyzers {
|
for name := range visitor.Identifiers {
|
||||||
a, ok := fullAnMap[name]
|
if isBuiltInAnalyzer(name) {
|
||||||
if !ok && !isBuiltInAnalyzer(name) {
|
continue
|
||||||
return nil, fmt.Errorf("rule %q uses unknown analyzer %q", rule.Name, name)
|
|
||||||
}
|
}
|
||||||
depAnMap[name] = a
|
// Check if it's one of the built-in functions, and if so,
|
||||||
|
// skip it as an analyzer & do initialization if necessary.
|
||||||
|
switch name {
|
||||||
|
case "geoip":
|
||||||
|
if err := geoMatcher.LoadGeoIP(); err != nil {
|
||||||
|
return nil, fmt.Errorf("rule %q failed to load geoip: %w", rule.Name, err)
|
||||||
}
|
}
|
||||||
if visitor.UseGeoSite {
|
case "geosite":
|
||||||
if err := geoMatcher.LoadGeoSite(); err != nil {
|
if err := geoMatcher.LoadGeoSite(); err != nil {
|
||||||
return nil, fmt.Errorf("rule %q failed to load geosite: %w", rule.Name, err)
|
return nil, fmt.Errorf("rule %q failed to load geosite: %w", rule.Name, err)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
a, ok := fullAnMap[name]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("rule %q uses unknown analyzer %q", rule.Name, name)
|
||||||
}
|
}
|
||||||
if visitor.UseGeoIp {
|
depAnMap[name] = a
|
||||||
if err := geoMatcher.LoadGeoIP(); err != nil {
|
|
||||||
return nil, fmt.Errorf("rule %q failed to load geoip: %w", rule.Name, err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cr := compiledExprRule{
|
cr := compiledExprRule{
|
||||||
Name: rule.Name,
|
Name: rule.Name,
|
||||||
Action: action,
|
Action: action,
|
||||||
Program: program,
|
Program: program,
|
||||||
Analyzers: visitor.Analyzers,
|
|
||||||
}
|
}
|
||||||
if action == ActionModify {
|
if action == ActionModify {
|
||||||
mod, ok := fullModMap[rule.Modifier.Name]
|
mod, ok := fullModMap[rule.Modifier.Name]
|
||||||
@ -175,6 +164,23 @@ func CompileExprRules(rules []ExprRule, ans []analyzer.Analyzer, mods []modifier
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerBuiltinFunctions(funcMap map[string]*ast.Function, geoMatcher *geo.GeoMatcher) {
|
||||||
|
funcMap["geoip"] = &ast.Function{
|
||||||
|
Name: "geoip",
|
||||||
|
Func: func(params ...any) (any, error) {
|
||||||
|
return geoMatcher.MatchGeoIp(params[0].(string), params[1].(string)), nil
|
||||||
|
},
|
||||||
|
Types: []reflect.Type{reflect.TypeOf(geoMatcher.MatchGeoIp)},
|
||||||
|
}
|
||||||
|
funcMap["geosite"] = &ast.Function{
|
||||||
|
Name: "geosite",
|
||||||
|
Func: func(params ...any) (any, error) {
|
||||||
|
return geoMatcher.MatchGeoSite(params[0].(string), params[1].(string)), nil
|
||||||
|
},
|
||||||
|
Types: []reflect.Type{reflect.TypeOf(geoMatcher.MatchGeoSite)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func streamInfoToExprEnv(info StreamInfo) map[string]interface{} {
|
func streamInfoToExprEnv(info StreamInfo) map[string]interface{} {
|
||||||
m := map[string]interface{}{
|
m := map[string]interface{}{
|
||||||
"id": info.ID,
|
"id": info.ID,
|
||||||
@ -241,22 +247,12 @@ func modifiersToMap(mods []modifier.Modifier) map[string]modifier.Modifier {
|
|||||||
return modMap
|
return modMap
|
||||||
}
|
}
|
||||||
|
|
||||||
type depVisitor struct {
|
type idVisitor struct {
|
||||||
Analyzers map[string]struct{}
|
Identifiers map[string]bool
|
||||||
|
|
||||||
UseGeoSite bool
|
|
||||||
UseGeoIp bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *depVisitor) Visit(node *ast.Node) {
|
func (v *idVisitor) Visit(node *ast.Node) {
|
||||||
if idNode, ok := (*node).(*ast.IdentifierNode); ok {
|
if idNode, ok := (*node).(*ast.IdentifierNode); ok {
|
||||||
switch idNode.Value {
|
v.Identifiers[idNode.Value] = true
|
||||||
case "geosite":
|
|
||||||
v.UseGeoSite = true
|
|
||||||
case "geoip":
|
|
||||||
v.UseGeoIp = true
|
|
||||||
default:
|
|
||||||
v.Analyzers[idNode.Value] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user