ftp: don't halt the flow when raising too_many_transactions

The first version of the event set done=true on state->curr_tx and
returned NULL when the limit hit. curr_tx is usually the active
command just received — marking it done mid-request throws off
response matching, and subsequent commands in the flow stop getting
logged.

SMB behavior is mirrored here:
Walk the tx list, find the oldest tx that isn't done, mark
it done and tag it with the event, then fall through and
create the new tx so the flow parsing continues. One stale tx gets
reaped per overflow so memory stays bounded.

Issue: 8489
pull/15344/head
Jeff Lucovsky 3 months ago committed by Victor Julien
parent 9ea2e29581
commit 5ddd808e9b

@ -223,11 +223,17 @@ static FTPTransaction *FTPTransactionCreate(FtpState *state)
SCEnter();
FTPTransaction *firsttx = TAILQ_FIRST(&state->tx_list);
if (firsttx && state->tx_cnt - firsttx->tx_id > ftp_config_maxtx) {
FTPTransaction *event_tx = state->curr_tx ? state->curr_tx : firsttx;
event_tx->done = true;
event_tx->tx_data.updated_ts = true;
SCAppLayerDecoderEventsSetEventRaw(&event_tx->tx_data.events, FtpEventTooManyTransactions);
return NULL;
FTPTransaction *tx_old;
TAILQ_FOREACH (tx_old, &state->tx_list, next) {
if (!tx_old->done) {
tx_old->done = true;
tx_old->tx_data.updated_ts = true;
tx_old->tx_data.updated_tc = true;
SCAppLayerDecoderEventsSetEventRaw(
&tx_old->tx_data.events, FtpEventTooManyTransactions);
break;
}
}
}
FTPTransaction *tx = FTPCalloc(1, sizeof(*tx));
if (tx == NULL) {

Loading…
Cancel
Save