]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
defrag: remove trackers on lookup
authorVictor Julien <vjulien@oisf.net>
Fri, 24 May 2024 17:11:41 +0000 (19:11 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 4 Jun 2024 04:28:26 +0000 (06:28 +0200)
When looking up a tracker, remove any timed out / completed trackers.

etc/schema.json
src/decode.c
src/decode.h
src/defrag-hash.c
src/defrag.c

index f72fd050f8ebde956973215adf3d3f6aa7df6084..276d2c0e1c80d41b176a229c626ff29801189378 100644 (file)
                                 }
                             },
                             "additionalProperties": false
+                        },
+                        "wrk": {
+                            "type": "object",
+                            "properties": {
+                                "tracker_timeout": {
+                                    "type": "integer"
+                                }
+                            },
+                            "additionalProperties": false
                         }
                     },
                     "additionalProperties": false
index e0deafabc97d2302df6fd47025d33afcaf069684..45234420529093d63967959f4b49eadb84c3ac67 100644 (file)
@@ -679,6 +679,7 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
     dtv->counter_defrag_no_frags = StatsRegisterCounter("defrag.max_frags_reached", tv);
     dtv->counter_defrag_tracker_soft_reuse = StatsRegisterCounter("defrag.tracker_soft_reuse", tv);
     dtv->counter_defrag_tracker_hard_reuse = StatsRegisterCounter("defrag.tracker_hard_reuse", tv);
+    dtv->counter_defrag_tracker_timeout = StatsRegisterCounter("defrag.wrk.tracker_timeout", tv);
 
     ExceptionPolicySetStatsCounters(tv, &dtv->counter_defrag_memcap_eps, &defrag_memcap_eps_stats,
             DefragGetMemcapExceptionPolicy(), "defrag.memcap_exception_policy.",
index a2961f43b365ec3cd0c1977bff37a3f2b97ea40a..eafdf35f4d5fe44a88635fb7fb04f3ee72839bc7 100644 (file)
@@ -1002,6 +1002,7 @@ typedef struct DecodeThreadVars_
     uint16_t counter_defrag_no_frags;
     uint16_t counter_defrag_tracker_soft_reuse;
     uint16_t counter_defrag_tracker_hard_reuse;
+    uint16_t counter_defrag_tracker_timeout;
     ExceptionPolicyCounters counter_defrag_memcap_eps;
 
     uint16_t counter_flow_memcap;
index 2340826dab1fabf52b8faeb2a33c0fe5559dcfb6..b5b21f37780a22c63edd4a610f5c2850dd914775 100644 (file)
@@ -555,27 +555,48 @@ DefragTracker *DefragGetTrackerFromHash(ThreadVars *tv, DecodeThreadVars *dtv, P
     }
 
     /* ok, we have a tracker in the bucket. Let's find out if it is our tracker */
+    DefragTracker *prev_dt = NULL;
     dt = hb->head;
 
     do {
+        DefragTracker *next_dt = NULL;
+
+        SCMutexLock(&dt->lock);
         if (DefragTrackerTimedOut(dt, p->ts)) {
-            dt->remove = 1;
+            next_dt = dt->hnext;
+            dt->hnext = NULL;
+            if (prev_dt) {
+                prev_dt->hnext = next_dt;
+            } else {
+                hb->head = next_dt;
+            }
+            DefragTrackerClearMemory(dt);
+            SCMutexUnlock(&dt->lock);
+
+            DefragTrackerMoveToSpare(dt);
+            StatsIncr(tv, dtv->counter_defrag_tracker_timeout);
+            goto tracker_removed;
         } else if (!dt->remove && DefragTrackerCompare(dt, p)) {
-            /* found our tracker, lock & return */
-            SCMutexLock(&dt->lock);
+            /* found our tracker, keep locked & return */
             (void)DefragTrackerIncrUsecnt(dt);
             DRLOCK_UNLOCK(hb);
             return dt;
         }
+        SCMutexUnlock(&dt->lock);
+        /* unless we removed 'dt', prev_dt needs to point to
+         * current 'dt' when adding a new tracker below. */
+        prev_dt = dt;
+        next_dt = dt->hnext;
 
-        if (dt->hnext == NULL) {
-            DefragTracker *prev = dt;
+    tracker_removed:
+        if (next_dt == NULL) {
             dt = DefragTrackerGetNew(tv, dtv, p);
             if (dt == NULL) {
                 DRLOCK_UNLOCK(hb);
                 return NULL;
             }
-            prev->hnext = dt;
+            dt->hnext = hb->head;
+            hb->head = dt;
 
             /* tracker is locked */
 
@@ -586,7 +607,7 @@ DefragTracker *DefragGetTrackerFromHash(ThreadVars *tv, DecodeThreadVars *dtv, P
             return dt;
         }
 
-        dt = dt->hnext;
+        dt = next_dt;
     } while (dt != NULL);
 
     /* should be unreachable */
index 1d55d9a944cb82f253dc566ef3b742c5d15379b0..6d647d6cc5a3670e707811c3ae4ce6ca9eb0ff1c 100644 (file)
@@ -2571,7 +2571,10 @@ static int DefragTrackerReuseTest(void)
 
     tracker2 = DefragGetTracker(&tv, &dtv, p1);
     FAIL_IF_NULL(tracker2);
-    FAIL_IF(tracker2 == tracker1);
+    /* DefragGetTracker will have returned tracker1 to the stack,
+     * the set up a new tracker. Since it pops the stack, it got
+     * tracker1. */
+    FAIL_IF(tracker2 != tracker1);
     FAIL_IF(tracker2->remove);
 
     SCFree(p1);