]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smtp: optimized tx iterator
authorPhilippe Antoine <pantoine@oisf.net>
Wed, 22 Mar 2023 16:24:40 +0000 (17:24 +0100)
committerVictor Julien <vjulien@oisf.net>
Sat, 1 Apr 2023 05:14:08 +0000 (07:14 +0200)
To be more efficient with larger number of transactions.
As was done for FTP.

Ticket: #5927
(cherry picked from commit f5f215dae7032d55fea7876a1716d30f0c68c4b7)

src/app-layer-smtp.c

index 414a2c7d30c95da9940107beaf82a6d222d67d7b..cc7c035ec26277d3df8f8cb4087d1407418c819a 100644 (file)
@@ -1697,6 +1697,44 @@ static AppLayerTxData *SMTPGetTxData(void *vtx)
     return &tx->tx_data;
 }
 
+/** \brief SMTP tx iterator, specialized for its linked list
+ *
+ *  \retval txptr or NULL if no more txs in list
+ */
+static AppLayerGetTxIterTuple SMTPGetTxIterator(const uint8_t ipproto, const AppProto alproto,
+        void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, AppLayerGetTxIterState *state)
+{
+    SMTPState *smtp_state = (SMTPState *)alstate;
+    AppLayerGetTxIterTuple no_tuple = { NULL, 0, false };
+    if (smtp_state) {
+        SMTPTransaction *tx_ptr;
+        if (state->un.ptr == NULL) {
+            tx_ptr = TAILQ_FIRST(&smtp_state->tx_list);
+        } else {
+            tx_ptr = (SMTPTransaction *)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;
+}
+
 /**
  * \brief Register the SMTP Protocol parser.
  */
@@ -1736,6 +1774,7 @@ void RegisterSMTPParsers(void)
         AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetAlstateProgress);
         AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetTxCnt);
         AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetTx);
+        AppLayerParserRegisterGetTxIterator(IPPROTO_TCP, ALPROTO_SMTP, SMTPGetTxIterator);
         AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPGetTxData);
         AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_SMTP,
                                                                SMTPStateGetAlstateProgressCompletionStatus);