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
+38 -14
View File
@@ -12,24 +12,32 @@ import (
"github.com/google/gopacket/layers"
)
var _ Engine = (*engine)(nil)
type workerPacket struct {
StreamID uint32
Data []byte
SrcMAC net.HardwareAddr
DstMAC net.HardwareAddr
SetVerdict func(io.Verdict, []byte) error
Packet io.Packet
StreamID uint32
Data []byte
SrcMAC net.HardwareAddr
DstMAC net.HardwareAddr
Gen int64
}
type workerResult struct {
Packet io.Packet
StreamID uint32
Verdict io.Verdict
ModifiedPacket []byte
Gen int64
}
type worker struct {
id int
packetChan chan *workerPacket
resultChan chan workerResult
logger Logger
macResolver *sourceMACResolver
tcpFlowMgr *tcpFlowManager
udpSM *udpStreamManager
tcpFlowMgr *tcpFlowManager
udpSM *udpStreamManager
modSerializeBuffer gopacket.SerializeBuffer
}
@@ -43,6 +51,9 @@ type workerConfig struct {
TCPMaxBufferedPagesTotal int // unused, kept for config compat
TCPMaxBufferedPagesPerConn int // unused, kept for config compat
UDPMaxStreams int
AnalyzerSelectionMode AnalyzerSelectionMode
ResultChan chan workerResult
Stats *statsCounters
}
func (c *workerConfig) fillDefaults() {
@@ -61,7 +72,8 @@ func newWorker(config workerConfig) (*worker, error) {
return nil, err
}
tcpMgr := newTCPFlowManager(config.ID, config.Logger, config.MACResolver, sfNode)
selector := newAnalyzerSelector(config.AnalyzerSelectionMode, config.Stats)
tcpMgr := newTCPFlowManager(config.ID, config.Logger, config.MACResolver, sfNode, selector)
if config.Ruleset != nil {
tcpMgr.updateRuleset(config.Ruleset, 0)
}
@@ -71,8 +83,10 @@ func newWorker(config workerConfig) (*worker, error) {
Logger: config.Logger,
Node: sfNode,
Ruleset: config.Ruleset,
Selector: selector,
Stats: config.Stats,
}
udpSM, err := newUDPStreamManager(udpSF, config.UDPMaxStreams)
udpSM, err := newUDPStreamManager(udpSF, config.UDPMaxStreams, config.Stats)
if err != nil {
return nil, err
}
@@ -80,6 +94,7 @@ func newWorker(config workerConfig) (*worker, error) {
return &worker{
id: config.ID,
packetChan: make(chan *workerPacket, config.ChanSize),
resultChan: config.ResultChan,
logger: config.Logger,
macResolver: config.MACResolver,
tcpFlowMgr: tcpMgr,
@@ -97,6 +112,10 @@ func (w *worker) Feed(p *workerPacket) bool {
}
}
func (w *worker) FeedBlocking(p *workerPacket) {
w.packetChan <- p
}
func (w *worker) Run(ctx context.Context) {
w.logger.WorkerStart(w.id)
defer w.logger.WorkerStop(w.id)
@@ -109,7 +128,13 @@ func (w *worker) Run(ctx context.Context) {
return
}
v, b := w.handle(wp)
_ = wp.SetVerdict(v, b)
w.resultChan <- workerResult{
Packet: wp.Packet,
StreamID: wp.StreamID,
Verdict: v,
ModifiedPacket: b,
Gen: wp.Gen,
}
}
}
}
@@ -185,8 +210,7 @@ func (w *worker) handleUDP(streamID uint32, l3 L3Info, udp UDPInfo, payload []by
SrcMAC: srcMAC,
DstMAC: dstMAC,
}
// Temporarily set payload on a UDP layer so existing UDP handling works
// We pass the payload through the context
// Temporarily set payload on a UDP layer so existing UDP handling works.
w.udpSM.MatchWithContext(streamID, ipFlow, &layers.UDP{
BaseLayer: layers.BaseLayer{Payload: payload},
SrcPort: layers.UDPPort(udp.SrcPort),