From 0b262cbfdac968cb5a05f46f2907bcdbf87f4fec Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 17 Mar 2015 23:05:07 +0100 Subject: [PATCH] dns: optimize tx list walks The detection engine and log engines can walk the tx list indirectly, by looping AppLayerParserGetTx. This would lead to new list walks in the DNS tx list though. Leading to bad performance. This patch stores the last returned tx and uses that to determine if the next tx is what we need next. If so, we can return that w/o list walk. --- src/app-layer-dns-common.c | 19 +++++++++++++++++++ src/app-layer-dns-common.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/app-layer-dns-common.c b/src/app-layer-dns-common.c index 95eaf13152..4d724dfaa4 100644 --- a/src/app-layer-dns-common.c +++ b/src/app-layer-dns-common.c @@ -173,15 +173,31 @@ void *DNSGetTx(void *alstate, uint64_t tx_id) DNSState *dns_state = (DNSState *)alstate; DNSTransaction *tx = NULL; + /* fast track: try the current tx */ if (dns_state->curr && dns_state->curr->tx_num == tx_id + 1) return dns_state->curr; + /* fast track: + * if the prev tx_id is equal to the stored tx ptr, we can + * use this shortcut to get to the next. */ + if (dns_state->iter) { + if (tx_id == dns_state->iter->tx_num) { + tx = TAILQ_NEXT(dns_state->iter, next); + if (tx && tx->tx_num == tx_id + 1) { + dns_state->iter = tx; + return tx; + } + } + } + + /* no luck with the fast tracks, do the full list walk */ TAILQ_FOREACH(tx, &dns_state->tx_list, next) { SCLogDebug("tx->tx_num %u, tx_id %"PRIu64, tx->tx_num, (tx_id+1)); if ((tx_id+1) != tx->tx_num) continue; SCLogDebug("returning tx %p", tx); + dns_state->iter = tx; return tx; } @@ -280,6 +296,9 @@ static void DNSTransactionFree(DNSTransaction *tx, DNSState *state) if (tx->de_state != NULL) DetectEngineStateFree(tx->de_state); + if (state->iter == tx) + state->iter = NULL; + DNSDecrMemcap(sizeof(DNSTransaction), state); SCFree(tx); SCReturn; diff --git a/src/app-layer-dns-common.h b/src/app-layer-dns-common.h index 5977a74df8..d795f0cba6 100644 --- a/src/app-layer-dns-common.h +++ b/src/app-layer-dns-common.h @@ -156,6 +156,7 @@ typedef struct DNSTransaction_ { typedef struct DNSState_ { TAILQ_HEAD(, DNSTransaction_) tx_list; /**< transaction list */ DNSTransaction *curr; /**< ptr to current tx */ + DNSTransaction *iter; uint64_t transaction_max; uint32_t unreplied_cnt; /**< number of unreplied requests in a row */ uint32_t memuse; /**< state memuse, for comparing with