]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http1: use a tx iterator 13235/head
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 13 May 2025 13:11:57 +0000 (15:11 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 14 May 2025 19:36:27 +0000 (21:36 +0200)
Better performance than the defaut iterator as we do not need to
read all first elements every time

rust/htp/src/c_api/connection_parser.rs
rust/htp/src/c_api/transaction.rs
rust/htp/src/connection_parser.rs
rust/htp/src/transactions.rs
src/app-layer-htp.c

index 017e67d5e7f58fe507dff1572387485ce8d3fe91..5afcc18f05d764af9e7e2b8d451fdc82f5048dc5 100644 (file)
@@ -219,6 +219,21 @@ pub unsafe extern "C" fn htp_connp_tx_size(connp: *const ConnectionParser) -> is
         .unwrap_or(-1)
 }
 
+/// Get a transaction by its index for the iterator.
+/// # Safety
+/// When calling this method, you have to ensure that connp is either properly initialized or NULL
+#[no_mangle]
+pub unsafe extern "C" fn htp_connp_tx_index(
+    connp: *mut ConnectionParser, index: usize,
+) -> *mut Transaction {
+    if let Some(tx) = connp.as_mut().unwrap().tx_index(index) {
+        if tx.is_started() {
+            return tx as *mut Transaction;
+        }
+    }
+    std::ptr::null_mut()
+}
+
 /// Get a transaction.
 ///
 /// Returns the transaction or NULL on error.
index a06f4d556e7e3b1f6f4980a7f60db9ad315620ed..6b2511fbf1da1e9d275aec5857ff19a6b186f1e8 100644 (file)
@@ -437,6 +437,17 @@ pub unsafe extern "C" fn htp_tx_flags(tx: *const Transaction) -> u64 {
     tx.as_ref().map(|tx| tx.flags).unwrap_or(0)
 }
 
+/// Get the transaction's index.
+///
+/// tx: Transaction pointer.
+///
+/// # Safety
+/// When calling this method, you have to ensure that tx is either properly initialized or NULL
+#[no_mangle]
+pub unsafe extern "C" fn htp_tx_index(tx: *const Transaction) -> usize {
+    tx.as_ref().map(|tx| tx.index).unwrap_or(0)
+}
+
 /// Get the transaction's request progress.
 ///
 /// tx: Transaction pointer.
index 90c172c22556c797903d4efd98f02cee62ab2374..d92ebe2b3525524a19197bb9271e1c0b269066f4 100644 (file)
@@ -462,6 +462,11 @@ impl ConnectionParser {
         self.transactions.get(index)
     }
 
+    /// Get a specific transaction by its index
+    pub(crate) fn tx_index(&mut self, index: usize) -> Option<&mut Transaction> {
+        self.transactions.get_index(index)
+    }
+
     /// Get a specific transaction
     pub(crate) fn tx_mut(&mut self, index: usize) -> Option<&mut Transaction> {
         self.transactions.get_mut(index)
index 584644ffb3762f1fd2b6f99cb6f016ce9ad6ecbd..f46824115ccc41e2276234b99b5d268925818823 100644 (file)
@@ -148,4 +148,12 @@ impl Transactions {
         }
         None
     }
+
+    /// Get the given transaction by index number
+    pub(crate) fn get_index(&mut self, index: usize) -> Option<&mut Transaction> {
+        if index < self.transactions.len() {
+            return Some(&mut self.transactions[index]);
+        }
+        None
+    }
 }
index 9d6bdd83bc33092a89743b9a6d8ca83e1aaf22bf..288cd99a8082e6c4a7a256441179edf78cc41dcb 100644 (file)
@@ -2482,6 +2482,34 @@ static void *HTPStateGetTx(void *alstate, uint64_t tx_id)
         return NULL;
 }
 
+static AppLayerGetTxIterTuple HTPGetTxIterator(const uint8_t ipproto, const AppProto alproto,
+        void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, AppLayerGetTxIterState *state)
+{
+    HtpState *http_state = (HtpState *)alstate;
+    uint64_t size = HTPStateGetTxCnt(alstate);
+    AppLayerGetTxIterTuple no_tuple = { NULL, 0, false };
+    if (http_state) {
+        while (state->un.u64 < size) {
+            htp_tx_t *tx = htp_connp_tx_index(http_state->connp, state->un.u64);
+            if (!tx) {
+                return no_tuple;
+            }
+            uint64_t tx_id = htp_tx_index(tx);
+            if (tx_id < min_tx_id) {
+                state->un.u64++;
+                continue;
+            }
+            AppLayerGetTxIterTuple tuple = {
+                .tx_ptr = tx,
+                .tx_id = tx_id,
+                .has_next = state->un.u64 < size,
+            };
+            return tuple;
+        }
+    }
+    return no_tuple;
+}
+
 void *HtpGetTxForH2(void *alstate)
 {
     // gets last transaction
@@ -2612,7 +2640,7 @@ void RegisterHTPParsers(void)
                 IPPROTO_TCP, ALPROTO_HTTP1, HTPStateGetAlstateProgress);
         AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP1, HTPStateGetTxCnt);
         AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_HTTP1, HTPStateGetTx);
-
+        AppLayerParserRegisterGetTxIterator(IPPROTO_TCP, ALPROTO_HTTP1, HTPGetTxIterator);
         AppLayerParserRegisterStateProgressCompletionStatus(
                 ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_COMPLETE, HTP_RESPONSE_PROGRESS_COMPLETE);
         AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_HTTP1, HTPStateGetEventInfo);