Improves flow handling and adds runtime stats APIs

Refactors TCP and UDP flow managers to enhance analyzer selection and flow binding accuracy, including O(1) UDP stream rebinding by 5-tuple.
Introduces runtime stats tracking for engine and ruleset operations, exposing new APIs for granular performance and error metrics.
Optimizes GeoMatcher with result caching and supports efficient geosite set matching, reducing redundant computation in ruleset expressions.
This commit is contained in:
2026-05-13 06:10:38 +05:30
parent 3f895adb43
commit 7a3f6e945d
23 changed files with 1440 additions and 152 deletions
+23 -2
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"runtime"
"git.difuse.io/Difuse/Mellaris/analyzer"
"git.difuse.io/Difuse/Mellaris/engine"
@@ -17,6 +18,7 @@ type App struct {
engine engine.Engine
io gfwio.PacketIO
rulesetConfig *ruleset.BuiltinConfig
ruleset ruleset.Ruleset
analyzers []analyzer.Analyzer
modifiers []modifier.Modifier
rulesFile string
@@ -42,6 +44,11 @@ func New(cfg Config, opts Options) (*App, error) {
packetIO := cfg.IO.PacketIO
ownsIO := false
workerCount := effectiveWorkerCount(cfg.Workers.Count)
numQueues := cfg.IO.NumQueues
if numQueues <= 0 {
numQueues = workerCount
}
if packetIO == nil {
packetIO, err = gfwio.NewNFQueuePacketIO(gfwio.NFQueuePacketIOConfig{
QueueSize: cfg.IO.QueueSize,
@@ -49,7 +56,7 @@ func New(cfg Config, opts Options) (*App, error) {
WriteBuffer: cfg.IO.WriteBuffer,
Local: cfg.IO.Local,
RST: cfg.IO.RST,
NumQueues: cfg.IO.NumQueues,
NumQueues: numQueues,
MaxPacketLen: cfg.IO.MaxPacketLen,
})
if err != nil {
@@ -79,11 +86,13 @@ func New(cfg Config, opts Options) (*App, error) {
Logger: engineLogger,
IO: packetIO,
Ruleset: rs,
Workers: cfg.Workers.Count,
Workers: workerCount,
WorkerQueueSize: cfg.Workers.QueueSize,
WorkerTCPMaxBufferedPagesTotal: cfg.Workers.TCPMaxBufferedPagesTotal,
WorkerTCPMaxBufferedPagesPerConn: cfg.Workers.TCPMaxBufferedPagesPerConn,
WorkerUDPMaxStreams: cfg.Workers.UDPMaxStreams,
OverflowPolicy: cfg.Workers.OverflowPolicy,
AnalyzerSelectionMode: cfg.Workers.AnalyzerSelectionMode,
}
eng, err := engine.NewEngine(engCfg)
if err != nil {
@@ -95,6 +104,7 @@ func New(cfg Config, opts Options) (*App, error) {
engine: eng,
io: packetIO,
rulesetConfig: rsConfig,
ruleset: rs,
analyzers: analyzers,
modifiers: modifiers,
rulesFile: rulesFile,
@@ -140,6 +150,17 @@ func (a *App) Engine() engine.Engine {
return a.engine
}
func effectiveWorkerCount(configured int) int {
if configured > 0 {
return configured
}
n := runtime.GOMAXPROCS(0)
if n <= 0 {
return 1
}
return n
}
func resolveRules(opts Options) ([]ruleset.ExprRule, string, error) {
if opts.RulesFile != "" && len(opts.Rules) > 0 {
return nil, "", ConfigError{Field: "rules", Err: errors.New("use either RulesFile or Rules")}