]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ftp: optimized tx iterator
authorPhilippe Antoine <contact@catenacyber.fr>
Fri, 29 Apr 2022 11:12:56 +0000 (13:12 +0200)
committerVictor Julien <vjulien@oisf.net>
Sat, 2 Jul 2022 05:42:49 +0000 (07:42 +0200)
To be more efficient with larger number of transactions.

Ticket: #5314
(cherry picked from commit 5a31b3508d6bec7df1a77e0422360c155a3de9f9)

src/app-layer-ftp.c

index 2793a7d33844dd4947d9fead1b574e9fef624694..b64a13efb0fa00be80f8079b0ff6ee1fe0d1e1dc 100644 (file)
@@ -1364,6 +1364,44 @@ static void FTPFreeMpmState(void)
     }
 }
 
+/** \brief FTP tx iterator, specialized for its linked list
+ *
+ *  \retval txptr or NULL if no more txs in list
+ */
+static AppLayerGetTxIterTuple FTPGetTxIterator(const uint8_t ipproto, const AppProto alproto,
+        void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, AppLayerGetTxIterState *state)
+{
+    FtpState *ftp_state = (FtpState *)alstate;
+    AppLayerGetTxIterTuple no_tuple = { NULL, 0, false };
+    if (ftp_state) {
+        FTPTransaction *tx_ptr;
+        if (state->un.ptr == NULL) {
+            tx_ptr = TAILQ_FIRST(&ftp_state->tx_list);
+        } else {
+            tx_ptr = (FTPTransaction *)state->un.ptr;
+        }
+        if (tx_ptr) {
+            while (tx_ptr->tx_id < min_tx_id) {
+                tx_ptr = TAILQ_NEXT(tx_ptr, next);
+                if (!tx_ptr) {
+                    return no_tuple;
+                }
+            }
+            if (tx_ptr->tx_id >= max_tx_id) {
+                return no_tuple;
+            }
+            state->un.ptr = TAILQ_NEXT(tx_ptr, next);
+            AppLayerGetTxIterTuple tuple = {
+                .tx_ptr = tx_ptr,
+                .tx_id = tx_ptr->tx_id,
+                .has_next = (state->un.ptr != NULL),
+            };
+            return tuple;
+        }
+    }
+    return no_tuple;
+}
+
 void RegisterFTPParsers(void)
 {
     const char *proto_name = "ftp";
@@ -1392,6 +1430,7 @@ void RegisterFTPParsers(void)
 
         AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_FTP, FTPGetTx);
         AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_FTP, FTPGetTxData);
+        AppLayerParserRegisterGetTxIterator(IPPROTO_TCP, ALPROTO_FTP, FTPGetTxIterator);
 
         AppLayerParserRegisterLocalStorageFunc(IPPROTO_TCP, ALPROTO_FTP, FTPLocalStorageAlloc,
                                                FTPLocalStorageFree);