App layer: clean up TX before lowest active one

Update DNS to handle cleaning up this way.
pull/418/merge
Victor Julien 12 years ago
parent 0b229ec8b9
commit 1367074c75

@ -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.

@ -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);

@ -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";

@ -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";

@ -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

Loading…
Cancel
Save