]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
App layer: clean up TX before lowest active one
authorVictor Julien <victor@inliniac.net>
Tue, 2 Jul 2013 10:33:11 +0000 (12:33 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 4 Jul 2013 11:52:12 +0000 (13:52 +0200)
Update DNS to handle cleaning up this way.

src/app-layer-dns-common.c
src/app-layer-dns-common.h
src/app-layer-dns-tcp.c
src/app-layer-dns-udp.c
src/app-layer-parser.c

index 95a49935e929437d1696a445334f44f256e4bdbe..1c3f164518e0c565045dbe8a845b2d1d5cea1bdd 100644 (file)
@@ -62,37 +62,6 @@ int DNSHasEvents(void *state) {
     return (dns_state->events > 0);
 }
 
-void *DNSStateAlloc(void) {
-    void *s = SCMalloc(sizeof(DNSState));
-    if (unlikely(s == NULL))
-        return NULL;
-
-    memset(s, 0, sizeof(DNSState));
-
-    DNSState *dns_state = (DNSState *)s;
-
-    TAILQ_INIT(&dns_state->tx_list);
-    return s;
-}
-
-void DNSStateFree(void *s) {
-    if (s) {
-        DNSState *dns_state = (DNSState *) s;
-
-        DNSTransaction *tx = NULL;
-        while ((tx = TAILQ_FIRST(&dns_state->tx_list))) {
-            TAILQ_REMOVE(&dns_state->tx_list, tx, next);
-            DNSTransactionFree(tx);
-        }
-
-        if (dns_state->buffer != NULL)
-            SCFree(dns_state->buffer);
-
-        SCFree(s);
-        s = NULL;
-    }
-}
-
 void *DNSGetTx(void *alstate, uint64_t tx_id) {
     DNSState *dns_state = (DNSState *)alstate;
     DNSTransaction *tx = NULL;
@@ -158,7 +127,7 @@ DNSTransaction *DNSTransactionAlloc(const uint16_t tx_id) {
 /** \internal
  *  \brief Free a DNS TX
  *  \param tx DNS TX to free */
-void DNSTransactionFree(DNSTransaction *tx) {
+static void DNSTransactionFree(DNSTransaction *tx) {
     DNSQueryEntry *q = NULL;
     while ((q = TAILQ_FIRST(&tx->query_list))) {
         TAILQ_REMOVE(&tx->query_list, q, next);
@@ -177,6 +146,40 @@ void DNSTransactionFree(DNSTransaction *tx) {
     SCFree(tx);
 }
 
+/**
+ *  \brief dns transaction cleanup callback
+ */
+void DNSStateTransactionFree(void *state, uint64_t tx_id) {
+    SCEnter();
+
+    DNSState *dns_state = state;
+    DNSTransaction *tx = NULL;
+
+    SCLogDebug("state %p, id %"PRIu64, dns_state, tx_id);
+
+    TAILQ_FOREACH(tx, &dns_state->tx_list, next) {
+        SCLogDebug("tx %p tx->tx_num %u, tx_id %"PRIu64, tx, tx->tx_num, (tx_id+1));
+        if ((tx_id+1) < tx->tx_num)
+            break;
+        else if ((tx_id+1) > tx->tx_num)
+            continue;
+
+        if (tx == dns_state->curr)
+            dns_state->curr = NULL;
+
+        if (tx->decoder_events != NULL) {
+            if (tx->decoder_events->cnt <= dns_state->events)
+                dns_state->events -= tx->decoder_events->cnt;
+            else
+                dns_state->events = 0;
+        }
+
+        TAILQ_REMOVE(&dns_state->tx_list, tx, next);
+        DNSTransactionFree(tx);
+        break;
+    }
+}
+
 /** \internal
  *  \brief Find the DNS Tx in the state
  *  \param tx_id id of the tx
@@ -202,6 +205,37 @@ DNSTransaction *DNSTransactionFindByTxId(const DNSState *dns_state, const uint16
     return NULL;
 }
 
+void *DNSStateAlloc(void) {
+    void *s = SCMalloc(sizeof(DNSState));
+    if (unlikely(s == NULL))
+        return NULL;
+
+    memset(s, 0, sizeof(DNSState));
+
+    DNSState *dns_state = (DNSState *)s;
+
+    TAILQ_INIT(&dns_state->tx_list);
+    return s;
+}
+
+void DNSStateFree(void *s) {
+    if (s) {
+        DNSState *dns_state = (DNSState *) s;
+
+        DNSTransaction *tx = NULL;
+        while ((tx = TAILQ_FIRST(&dns_state->tx_list))) {
+            TAILQ_REMOVE(&dns_state->tx_list, tx, next);
+            DNSTransactionFree(tx);
+        }
+
+        if (dns_state->buffer != NULL)
+            SCFree(dns_state->buffer);
+
+        SCFree(s);
+        s = NULL;
+    }
+}
+
 /** \brief Validation checks for DNS request header
  *
  *  Will set decoder events if anomalies are found.
index ae1a8c663a9f04ac642487da82665575deba7748..7a7e99d34c897d1f0bf2bb2eafaa95c84c632d9f 100644 (file)
@@ -161,7 +161,7 @@ int DNSGetAlstateProgress(void *tx, uint8_t direction);
 int DNSGetAlstateProgressCompletionStatus(uint8_t direction);
 
 DNSTransaction *DNSTransactionAlloc(const uint16_t tx_id);
-void DNSTransactionFree(DNSTransaction *tx);
+void DNSStateTransactionFree(void *state, uint64_t tx_id);
 DNSTransaction *DNSTransactionFindByTxId(const DNSState *dns_state, const uint16_t tx_id);
 
 void DNSSetEvent(DNSState *s, uint8_t e);
index 8a11496d7982b27ee9e2927bf51fff101df1074f..109c9e07abcbaee418d10f9e028d2c523f512653 100644 (file)
@@ -572,45 +572,6 @@ static uint16_t DNSTcpProbingParser(uint8_t *input, uint32_t ilen)
     return ALPROTO_DNS_TCP;
 }
 
-/**
- *  \brief Update the transaction id based on the dns state
- */
-void DNSStateUpdateTransactionId(void *state, uint16_t *id) {
-    SCEnter();
-
-    DNSState *s = state;
-
-    SCLogDebug("original id %"PRIu16", s->transaction_max %"PRIu64,
-            *id, (s->transaction_max));
-
-    if ((s->transaction_max) > (*id)) {
-        SCLogDebug("original id %"PRIu16", updating with s->transaction_max %"PRIu64,
-                *id, (s->transaction_max));
-
-        (*id) = (s->transaction_max);
-
-        SCLogDebug("updated id %"PRIu16, *id);
-    }
-
-    SCReturn;
-}
-
-/**
- *  \brief dns transaction cleanup callback
- */
-void DNSStateTransactionFree(void *state, uint64_t id) {
-    SCEnter();
-
-    DNSState *s = state;
-
-    SCLogDebug("state %p, id %"PRIu64, s, id);
-
-    /* we can't remove the actual transactions here */
-
-    SCReturn;
-}
-
-
 void RegisterDNSTCPParsers(void) {
     char *proto_name = "dnstcp";
 
index 2e8f8bc247bea671f7f730001e4b42f2d1a480d1..b642e06137c7ac0b34f073aba32d68afd4bf7e5d 100644 (file)
@@ -293,21 +293,6 @@ static uint16_t DNSUdpProbingParser(uint8_t *input, uint32_t ilen)
     return ALPROTO_DNS_UDP;
 }
 
-/**
- *  \brief dns transaction cleanup callback
- */
-static void DNSStateTransactionFree(void *state, uint64_t id) {
-    SCEnter();
-
-    DNSState *s = state;
-
-    SCLogDebug("state %p, id %"PRIu64, s, id);
-
-    /* we can't remove the actual transactions here */
-
-    SCReturn;
-}
-
 
 void RegisterDNSUDPParsers(void) {
     char *proto_name = "dnsudp";
index 0d73db58d11d23e412aafe30dbea22a58d03e5a2..41a899d29d341c7d2bda00f21ec5979a50728664 100644 (file)
@@ -953,32 +953,30 @@ static int AppLayerDoParse(void *local_data, Flow *f,
 /**
  * \brief remove obsolete (inspected and logged) transactions
  */
-static int AppLayerTransactionsCleanup(AppLayerProto *p, AppLayerParserStateStore *parser_state_store, void *app_layer_state)
+static void AppLayerTransactionsCleanup(AppLayerProto *p, AppLayerParserStateStore *parser_state_store, void *app_layer_state)
 {
-    uint64_t low;
-
     if (p->StateTransactionFree == NULL)
-        goto end;
+        return;
+
+    uint64_t inspect = 0, log = 0;
+    if (parser_state_store->inspect_id[0] < parser_state_store->inspect_id[1])
+        inspect = parser_state_store->inspect_id[0];
+    else
+        inspect = parser_state_store->inspect_id[1];
+    log = parser_state_store->log_id;
 
     if (p->logger == TRUE) {
-        if (parser_state_store->inspect_id[0] < parser_state_store->inspect_id[1])
-            low = parser_state_store->inspect_id[0];
-        else
-            low = parser_state_store->inspect_id[1];
-        if (parser_state_store->log_id < low) {
-            low = parser_state_store->log_id;
+        uint64_t min = log < inspect ? log : inspect;
+        if (min > 0) {
+            SCLogDebug("freeing %"PRIu64" (with logger) %p", min - 1, p->StateTransactionFree);
+            p->StateTransactionFree(app_layer_state, min - 1);
         }
     } else {
-        if (parser_state_store->inspect_id[0] < parser_state_store->inspect_id[1])
-            low = parser_state_store->inspect_id[0];
-        else
-            low = parser_state_store->inspect_id[1];
+        if (inspect > 0) {
+            SCLogDebug("freeing %"PRIu64" (no logger) %p", inspect - 1, p->StateTransactionFree);
+            p->StateTransactionFree(app_layer_state, inspect - 1);
+        }
     }
-
-    p->StateTransactionFree(app_layer_state, low);
-
-end:
-    return 0;
 }
 
 #ifdef DEBUG