engine: more performance improvements
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package ruleset
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -12,6 +13,13 @@ import (
|
||||
"github.com/expr-lang/expr/parser"
|
||||
)
|
||||
|
||||
type testAnalyzer struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (a testAnalyzer) Name() string { return a.name }
|
||||
func (a testAnalyzer) Limit() int { return 0 }
|
||||
|
||||
func TestExtractGeoSiteConditions(t *testing.T) {
|
||||
expression := `
|
||||
(geosite(tls.req.sni, "openai") || geosite(quic.req.sni, "OpenAI")) &&
|
||||
@@ -88,3 +96,93 @@ func TestIDPatcher_PatchesGeoSiteORChainToGeoSiteSet(t *testing.T) {
|
||||
t.Fatalf("expected OR chain to be collapsed, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompileExprRulesPrunesUnusedAnalyzers(t *testing.T) {
|
||||
rs, err := CompileExprRules([]ExprRule{
|
||||
{Name: "network-only", Action: "allow", Expr: `proto == "tcp" && port.dst == 443`},
|
||||
}, []analyzer.Analyzer{testAnalyzer{name: "tls"}, testAnalyzer{name: "quic"}}, nil, &BuiltinConfig{})
|
||||
if err != nil {
|
||||
t.Fatalf("CompileExprRules error: %v", err)
|
||||
}
|
||||
exprRS := rs.(*exprRuleset)
|
||||
if len(exprRS.Ans) != 0 {
|
||||
t.Fatalf("expected no analyzers for network-only rule, got %d", len(exprRS.Ans))
|
||||
}
|
||||
if exprRS.Rules[0].Native == nil {
|
||||
t.Fatalf("expected network-only rule to compile to native matcher")
|
||||
}
|
||||
got := rs.Match(StreamInfo{Protocol: ProtocolTCP, DstPort: 443})
|
||||
if got.Action != ActionAllow {
|
||||
t.Fatalf("native match action=%v want=%v", got.Action, ActionAllow)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompileExprRulesKeepsReferencedAnalyzersOnly(t *testing.T) {
|
||||
rs, err := CompileExprRules([]ExprRule{
|
||||
{Name: "tls-only", Action: "allow", Expr: `tls != nil && tls.req != nil && tls.req.sni == "example.com"`},
|
||||
}, []analyzer.Analyzer{testAnalyzer{name: "tls"}, testAnalyzer{name: "quic"}}, nil, &BuiltinConfig{})
|
||||
if err != nil {
|
||||
t.Fatalf("CompileExprRules error: %v", err)
|
||||
}
|
||||
exprRS := rs.(*exprRuleset)
|
||||
if len(exprRS.Ans) != 1 || exprRS.Ans[0].Name() != "tls" {
|
||||
t.Fatalf("expected only tls analyzer, got %#v", exprRS.Ans)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNativeCIDRMatcher(t *testing.T) {
|
||||
funcMap, geoMatcher := buildFunctionMapForTest()
|
||||
n := compileNativeExpr(`cidr(ip.src, "192.168.1.0/24") && port.dst >= 80 && port.dst <= 443`, funcMap, geoMatcher)
|
||||
if n == nil {
|
||||
t.Fatal("expected native matcher")
|
||||
}
|
||||
if !n.Match(StreamInfo{SrcIP: net.ParseIP("192.168.1.10"), DstPort: 443}) {
|
||||
t.Fatal("expected native CIDR matcher to match")
|
||||
}
|
||||
if n.Match(StreamInfo{SrcIP: net.ParseIP("10.0.0.1"), DstPort: 443}) {
|
||||
t.Fatal("expected native CIDR matcher not to match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanFinalizeAfterLogForRequestOnlyActionRules(t *testing.T) {
|
||||
rs, err := CompileExprRules([]ExprRule{
|
||||
{Name: "log-host", Log: true, Expr: `tls != nil && tls.req != nil && tls.req.sni != nil`},
|
||||
{Name: "block-bad-host", Action: "block", Expr: `tls != nil && tls.req != nil && tls.req.sni == "bad.example"`},
|
||||
}, []analyzer.Analyzer{testAnalyzer{name: "tls"}}, nil, &BuiltinConfig{})
|
||||
if err != nil {
|
||||
t.Fatalf("CompileExprRules error: %v", err)
|
||||
}
|
||||
|
||||
info := StreamInfo{
|
||||
Props: analyzer.CombinedPropMap{
|
||||
"tls": analyzer.PropMap{"req": analyzer.PropMap{"sni": "good.example"}},
|
||||
},
|
||||
}
|
||||
if !rs.(LogFinalizer).CanFinalizeAfterLog(info, []string{"tls"}) {
|
||||
t.Fatal("expected request-only rules to allow log finalization once request props exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanFinalizeAfterLogWaitsForResponseActionRules(t *testing.T) {
|
||||
rs, err := CompileExprRules([]ExprRule{
|
||||
{Name: "log-host", Log: true, Expr: `tls != nil && tls.req != nil && tls.req.sni != nil`},
|
||||
{Name: "block-response", Action: "block", Expr: `tls != nil && tls.resp != nil && tls.resp.cipher_suite == "bad"`},
|
||||
}, []analyzer.Analyzer{testAnalyzer{name: "tls"}}, nil, &BuiltinConfig{})
|
||||
if err != nil {
|
||||
t.Fatalf("CompileExprRules error: %v", err)
|
||||
}
|
||||
|
||||
info := StreamInfo{
|
||||
Props: analyzer.CombinedPropMap{
|
||||
"tls": analyzer.PropMap{"req": analyzer.PropMap{"sni": "good.example"}},
|
||||
},
|
||||
}
|
||||
if rs.(LogFinalizer).CanFinalizeAfterLog(info, []string{"tls"}) {
|
||||
t.Fatal("expected response-side rule to keep inspection open")
|
||||
}
|
||||
}
|
||||
|
||||
func buildFunctionMapForTest() (map[string]*Function, *geo.GeoMatcher) {
|
||||
m, g := buildFunctionMap(&BuiltinConfig{}, nil)
|
||||
return m, g
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user