]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ftp: optimized tx iterator 7619/head 7620/head
authorPhilippe Antoine <contact@catenacyber.fr>
Fri, 29 Apr 2022 11:12:56 +0000 (13:12 +0200)
committerJason Ish <jason.ish@oisf.net>
Thu, 7 Jul 2022 14:56:34 +0000 (09:56 -0500)
To be more efficient with larger number of transactions.

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

src/app-layer-ftp.c

index 7d6d989b7e69f2a71a573ad8d58f11f79582b419..7fcad47c0828d5067039eed8a4b84dd7b8e04a59 100644 (file)
@@ -1389,6 +1389,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";
@@ -1421,6 +1459,7 @@ void RegisterFTPParsers(void)
         AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_FTP, FTPGetTx);
         AppLayerParserRegisterLoggerFuncs(IPPROTO_TCP, ALPROTO_FTP, FTPStateGetTxLogged,
                                           FTPStateSetTxLogged);
+        AppLayerParserRegisterGetTxIterator(IPPROTO_TCP, ALPROTO_FTP, FTPGetTxIterator);
 
         AppLayerParserRegisterLocalStorageFunc(IPPROTO_TCP, ALPROTO_FTP, FTPLocalStorageAlloc,
                                                FTPLocalStorageFree);