From: Philippe Antoine Date: Wed, 22 Mar 2023 16:24:40 +0000 (+0100) Subject: smtp: optimized tx iterator X-Git-Tag: suricata-6.0.11~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8fd0862f94a9048e3968011d9605d74b29cf22bf;p=thirdparty%2Fsuricata.git smtp: optimized tx iterator To be more efficient with larger number of transactions. As was done for FTP. Ticket: #5927 (cherry picked from commit f5f215dae7032d55fea7876a1716d30f0c68c4b7) --- diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index 414a2c7d30..cc7c035ec2 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -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);