feat(tcp, udp): implement stream state release after verdict and adjust flush interval logic

This commit is contained in:
2026-09-12 17:20:24 +08:00
parent cc6ad72706
commit 8f8cc1d4d9
4 changed files with 254 additions and 12 deletions
+14 -5
View File
@@ -160,7 +160,6 @@ type udpStream struct {
logger Logger
ruleset ruleset.Ruleset
activeEntries []*udpStreamEntry
doneEntries []*udpStreamEntry
lastVerdict udpVerdict
}
@@ -194,7 +193,6 @@ func (s *udpStream) Feed(udp *layers.UDP, rev bool, uc *udpContext) {
updated = updated || up1 || up2
if done {
s.activeEntries = append(s.activeEntries[:i], s.activeEntries[i+1:]...)
s.doneEntries = append(s.doneEntries, entry)
}
}
if updated || s.virgin {
@@ -236,14 +234,19 @@ func (s *udpStream) Feed(udp *layers.UDP, rev bool, uc *udpContext) {
uc.Verdict = udpVerdictAcceptStream
s.logger.UDPStreamAction(s.info, ruleset.ActionAllow, true)
}
if len(s.activeEntries) == 0 {
// 同 tcpStream.release:这条流会在 LRU 里一直待到被挤出去,别让它带着分析器一起等
s.release()
}
}
func (s *udpStream) Close() {
s.closeActiveEntries()
s.release()
}
func (s *udpStream) closeActiveEntries() {
// Signal close to all active entries & move them to doneEntries
// Signal close to all active entries
updated := false
for _, entry := range s.activeEntries {
update := entry.Stream.Close(false)
@@ -253,16 +256,22 @@ func (s *udpStream) closeActiveEntries() {
if updated {
s.logger.UDPStreamPropUpdate(s.info, true)
}
s.doneEntries = append(s.doneEntries, s.activeEntries...)
s.activeEntries = nil
}
// release 在最终判定发出后丢掉不会再用到的状态,Accept 此后只看 lastVerdict
func (s *udpStream) release() {
s.activeEntries = nil
s.info.Props = nil
s.ruleset = nil
}
func (s *udpStream) feedEntry(entry *udpStreamEntry, rev bool, data []byte) (update *analyzer.PropUpdate, closeUpdate *analyzer.PropUpdate, done bool) {
update, done = entry.Stream.Feed(rev, data)
if entry.HasLimit {
entry.Quota -= len(data)
if entry.Quota <= 0 {
// Quota exhausted, signal close & move to doneEntries
// Quota exhausted, signal close & drop the entry
closeUpdate = entry.Stream.Close(true)
done = true
}