]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http1: remove transactions from their list
authorPhilippe Antoine <pantoine@oisf.net>
Fri, 7 Apr 2023 14:02:41 +0000 (16:02 +0200)
committerVictor Julien <vjulien@oisf.net>
Wed, 7 Feb 2024 04:59:31 +0000 (05:59 +0100)
instead of keeping a NULL pointer in an array

Ticket: #5921

(cherry picked from commit 8f63a8f3bffbbaf8fae4985ee5f974ab326b08c0)

src/app-layer-htp.c
src/app-layer-htp.h

index f232b2f7e4de1126fdade5d2f4ff3dedc823408e..05e2777f3bac13d5ebd28994dfd498b4fd567166 100644 (file)
@@ -402,7 +402,7 @@ void HTPStateFree(void *state)
         uint64_t total_txs = HTPStateGetTxCnt(state);
         /* free the list of body chunks */
         if (s->conn != NULL) {
-            for (tx_id = 0; tx_id < total_txs; tx_id++) {
+            for (tx_id = s->tx_freed; tx_id < total_txs; tx_id++) {
                 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
                 if (tx != NULL) {
                     HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx);
@@ -461,8 +461,10 @@ static void HTPStateTransactionFree(void *state, uint64_t id)
             tx->request_progress = HTP_REQUEST_COMPLETE;
             tx->response_progress = HTP_RESPONSE_COMPLETE;
         }
+        // replaces tx in the s->conn->transactions list by NULL
         htp_tx_destroy(tx);
     }
+    s->tx_freed += htp_connp_tx_freed(s->connp);
 }
 
 /**
@@ -2976,7 +2978,7 @@ static uint64_t HTPStateGetTxCnt(void *alstate)
         if (size < 0)
             return 0ULL;
         SCLogDebug("size %"PRIu64, size);
-        return (uint64_t)size;
+        return (uint64_t)size + http_state->tx_freed;
     } else {
         return 0ULL;
     }
@@ -2986,8 +2988,8 @@ static void *HTPStateGetTx(void *alstate, uint64_t tx_id)
 {
     HtpState *http_state = (HtpState *)alstate;
 
-    if (http_state != NULL && http_state->conn != NULL)
-        return htp_list_get(http_state->conn->transactions, tx_id);
+    if (http_state != NULL && http_state->conn != NULL && tx_id >= http_state->tx_freed)
+        return htp_list_get(http_state->conn->transactions, tx_id - http_state->tx_freed);
     else
         return NULL;
 }
@@ -2997,9 +2999,9 @@ void *HtpGetTxForH2(void *alstate)
     // gets last transaction
     HtpState *http_state = (HtpState *)alstate;
     if (http_state != NULL && http_state->conn != NULL) {
-        size_t txid = htp_list_array_size(http_state->conn->transactions);
-        if (txid > 0) {
-            return htp_list_get(http_state->conn->transactions, txid - 1);
+        size_t txid = HTPStateGetTxCnt(http_state);
+        if (txid > http_state->tx_freed) {
+            return htp_list_get(http_state->conn->transactions, txid - http_state->tx_freed - 1);
         }
     }
     return NULL;
index d6fa4f00954a67036f4ceeea614964ccbd71aa64..0380a950b5b5845922f5b2b8484eafab08335818 100644 (file)
@@ -252,6 +252,13 @@ typedef struct HtpState_ {
     uint64_t store_tx_id;
     FileContainer *files_ts;
     FileContainer *files_tc;
+    // tx_freed is the number of already freed transactions
+    // This is needed as libhtp only keeps the live transactions :
+    // To get the total number of transactions, we need to add
+    // the number of transactions tracked by libhtp to this number.
+    // It is also needed as an offset to translate between suricata
+    // transaction id to libhtp offset in its list/array
+    uint64_t tx_freed;
     const struct HTPCfgRec_ *cfg;
     uint16_t flags;
     uint16_t events;