app-layer: use logger bits to avoid looping

Avoid looping in transaction output.

Update app-layer API to store the bits in one step
and retrieve the bits in a single step as well.

Update users of the API.
pull/3135/head
Victor Julien 8 years ago
parent 01724f04fa
commit bca0cd71ae

@ -29,6 +29,14 @@ impl LoggerFlags {
}
}
pub fn get(&self) -> u32 {
self.flags
}
pub fn set(&mut self, bits: u32) {
self.flags = bits;
}
pub fn set_logged(&mut self, logger: u32) {
self.flags |= logger;
}

@ -687,21 +687,17 @@ pub extern "C" fn rs_dns_tx_get_alstate_progress(_tx: &mut DNSTransaction,
#[no_mangle]
pub extern "C" fn rs_dns_tx_set_logged(_state: &mut DNSState,
tx: &mut DNSTransaction,
logger: libc::uint32_t)
logged: libc::uint32_t)
{
tx.logged.set_logged(logger);
tx.logged.set(logged);
}
#[no_mangle]
pub extern "C" fn rs_dns_tx_get_logged(_state: &mut DNSState,
tx: &mut DNSTransaction,
logger: libc::uint32_t)
-> i8
tx: &mut DNSTransaction)
-> u32
{
if tx.logged.is_logged(logger) {
return 1;
}
return 0;
return tx.logged.get();
}
#[no_mangle]

@ -1869,21 +1869,17 @@ pub extern "C" fn rs_nfs3_reset_txs_updated(state: &mut NFSState,
#[no_mangle]
pub extern "C" fn rs_nfs3_tx_set_logged(_state: &mut NFSState,
tx: &mut NFSTransaction,
logger: libc::uint32_t)
logged: libc::uint32_t)
{
tx.logged.set_logged(logger);
tx.logged.set(logged);
}
#[no_mangle]
pub extern "C" fn rs_nfs3_tx_get_logged(_state: &mut NFSState,
tx: &mut NFSTransaction,
logger: libc::uint32_t)
-> i8
tx: &mut NFSTransaction)
-> u32
{
if tx.logged.is_logged(logger) {
return 1;
}
return 0;
return tx.logged.get();
}
#[no_mangle]

@ -139,7 +139,7 @@ pub type SetDetectStateFn = extern "C" fn (*mut c_void, *mut c_void, &mut Dete
pub type GetEventInfoFn = extern "C" fn (*const c_char, *mut c_int, *mut AppLayerEventType) -> c_int;
pub type GetEventsFn = extern "C" fn (*mut c_void, u64) -> *mut AppLayerDecoderEvents;
pub type HasEventsFn = extern "C" fn (*mut c_void) -> c_int;
pub type GetTxLoggedFn = extern "C" fn (*mut c_void, *mut c_void, u32) -> c_int;
pub type GetTxLoggedFn = extern "C" fn (*mut c_void, *mut c_void) -> u32;
pub type SetTxLoggedFn = extern "C" fn (*mut c_void, *mut c_void, u32);
pub type LocalStorageNewFn = extern "C" fn () -> *mut c_void;
pub type LocalStorageFreeFn = extern "C" fn (*mut c_void);

@ -1542,20 +1542,16 @@ static int DNP3SetTxDetectState(void *state, void *vtx, DetectEngineState *s)
return 0;
}
static void DNP3SetTxLogged(void *alstate, void *vtx, uint32_t logger)
static void DNP3SetTxLogged(void *alstate, void *vtx, LoggerId logged)
{
DNP3Transaction *tx = (DNP3Transaction *)vtx;
tx->logged |= logger;
tx->logged = logged;
}
static int DNP3GetTxLogged(void *alstate, void *vtx, uint32_t logger)
static LoggerId DNP3GetTxLogged(void *alstate, void *vtx)
{
DNP3Transaction *tx = (DNP3Transaction *)vtx;
if (tx->logged & logger) {
return 1;
}
return 0;
return tx->logged;
}
/**

@ -236,19 +236,16 @@ int DNSGetAlstateProgress(void *tx, uint8_t direction)
}
}
void DNSSetTxLogged(void *alstate, void *tx, uint32_t logger)
void DNSSetTxLogged(void *alstate, void *tx, LoggerId logged)
{
DNSTransaction *dns_tx = (DNSTransaction *)tx;
dns_tx->logged |= logger;
dns_tx->logged = logged;
}
int DNSGetTxLogged(void *alstate, void *tx, uint32_t logger)
LoggerId DNSGetTxLogged(void *alstate, void *tx)
{
DNSTransaction *dns_tx = (DNSTransaction *)tx;
if (dns_tx->logged & logger)
return 1;
return 0;
return dns_tx->logged;
}
/** \brief get value for 'complete' status in DNS

@ -267,8 +267,8 @@ void DNSAppLayerRegisterGetEventInfo(uint8_t ipproto, AppProto alproto);
void *DNSGetTx(void *alstate, uint64_t tx_id);
uint64_t DNSGetTxCnt(void *alstate);
void DNSSetTxLogged(void *alstate, void *tx, uint32_t logger);
int DNSGetTxLogged(void *alstate, void *tx, uint32_t logger);
void DNSSetTxLogged(void *alstate, void *tx, LoggerId logged);
LoggerId DNSGetTxLogged(void *alstate, void *tx);
int DNSGetAlstateProgress(void *tx, uint8_t direction);
int DNSGetAlstateProgressCompletionStatus(uint8_t direction);

@ -83,14 +83,14 @@ static void *RustDNSGetTx(void *alstate, uint64_t tx_id)
return rs_dns_state_get_tx(alstate, tx_id);
}
static void RustDNSSetTxLogged(void *alstate, void *tx, uint32_t logger)
static void RustDNSSetTxLogged(void *alstate, void *tx, LoggerId logged)
{
rs_dns_tx_set_logged(alstate, tx, logger);
rs_dns_tx_set_logged(alstate, tx, logged);
}
static int RustDNSGetTxLogged(void *alstate, void *tx, uint32_t logger)
static LoggerId RustDNSGetTxLogged(void *alstate, void *tx)
{
return rs_dns_tx_get_logged(alstate, tx, logger);
return rs_dns_tx_get_logged(alstate, tx);
}
static void RustDNSStateTransactionFree(void *state, uint64_t tx_id)

@ -80,14 +80,14 @@ static void *RustDNSGetTx(void *alstate, uint64_t tx_id)
return rs_dns_state_get_tx(alstate, tx_id);
}
static void RustDNSSetTxLogged(void *alstate, void *tx, uint32_t logger)
static void RustDNSSetTxLogged(void *alstate, void *tx, LoggerId logged)
{
rs_dns_tx_set_logged(alstate, tx, logger);
rs_dns_tx_set_logged(alstate, tx, logged);
}
static int RustDNSGetTxLogged(void *alstate, void *tx, uint32_t logger)
static LoggerId RustDNSGetTxLogged(void *alstate, void *tx)
{
return rs_dns_tx_get_logged(alstate, tx, logger);
return rs_dns_tx_get_logged(alstate, tx);
}
static void RustDNSStateTransactionFree(void *state, uint64_t tx_id)

@ -2671,20 +2671,20 @@ static void *HTPStateGetTx(void *alstate, uint64_t tx_id)
return NULL;
}
static void HTPStateSetTxLogged(void *alstate, void *vtx, uint32_t logger)
static void HTPStateSetTxLogged(void *alstate, void *vtx, LoggerId bits)
{
htp_tx_t *tx = (htp_tx_t *)vtx;
HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx);
if (tx_ud)
tx_ud->logged |= logger;
tx_ud->logged = bits;
}
static int HTPStateGetTxLogged(void *alstate, void *vtx, uint32_t logger)
static LoggerId HTPStateGetTxLogged(void *alstate, void *vtx)
{
htp_tx_t *tx = (htp_tx_t *)vtx;
HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx);
if (tx_ud && (tx_ud->logged & logger))
return 1;
if (tx_ud != NULL)
return tx_ud->logged;
return 0;
}

@ -262,19 +262,16 @@ static void *ModbusGetTx(void *alstate, uint64_t tx_id)
return NULL;
}
static void ModbusSetTxLogged(void *alstate, void *vtx, uint32_t logger)
static void ModbusSetTxLogged(void *alstate, void *vtx, LoggerId logged)
{
ModbusTransaction *tx = (ModbusTransaction *)vtx;
tx->logged |= logger;
tx->logged = logged;
}
static int ModbusGetTxLogged(void *alstate, void *vtx, uint32_t logger)
static LoggerId ModbusGetTxLogged(void *alstate, void *vtx)
{
ModbusTransaction *tx = (ModbusTransaction *)vtx;
if (tx->logged & logger)
return 1;
return 0;
return tx->logged;
}
static uint64_t ModbusGetTxCnt(void *alstate)

@ -182,14 +182,14 @@ static void *NFSTCPGetTx(void *state, uint64_t tx_id)
return rs_nfs3_state_get_tx(state, tx_id);
}
static void NFSTCPSetTxLogged(void *state, void *vtx, uint32_t logger)
static void NFSTCPSetTxLogged(void *state, void *vtx, LoggerId logged)
{
rs_nfs3_tx_set_logged(state, vtx, logger);
rs_nfs3_tx_set_logged(state, vtx, logged);
}
static int NFSTCPGetTxLogged(void *state, void *vtx, uint32_t logger)
static LoggerId NFSTCPGetTxLogged(void *state, void *vtx)
{
return rs_nfs3_tx_get_logged(state, vtx, logger);
return rs_nfs3_tx_get_logged(state, vtx);
}
/**

@ -187,14 +187,14 @@ static void *NFSGetTx(void *state, uint64_t tx_id)
return rs_nfs3_state_get_tx(state, tx_id);
}
static void NFSSetTxLogged(void *state, void *vtx, uint32_t logger)
static void NFSSetTxLogged(void *state, void *vtx, LoggerId logged)
{
rs_nfs3_tx_set_logged(state, vtx, logger);
rs_nfs3_tx_set_logged(state, vtx, logged);
}
static int NFSGetTxLogged(void *state, void *vtx, uint32_t logger)
static LoggerId NFSGetTxLogged(void *state, void *vtx)
{
return rs_nfs3_tx_get_logged(state, vtx, logger);
return rs_nfs3_tx_get_logged(state, vtx);
}
/**

@ -110,8 +110,8 @@ typedef struct AppLayerParserProtoCtx_
int (*StateGetEventInfo)(const char *event_name,
int *event_id, AppLayerEventType *event_type);
int (*StateGetTxLogged)(void *alstate, void *tx, uint32_t logger);
void (*StateSetTxLogged)(void *alstate, void *tx, uint32_t logger);
LoggerId (*StateGetTxLogged)(void *alstate, void *tx);
void (*StateSetTxLogged)(void *alstate, void *tx, LoggerId logger);
int (*StateHasTxDetectState)(void *alstate);
DetectEngineState *(*GetTxDetectState)(void *tx);
@ -440,8 +440,8 @@ void AppLayerParserRegisterHasEventsFunc(uint8_t ipproto, AppProto alproto,
}
void AppLayerParserRegisterLoggerFuncs(uint8_t ipproto, AppProto alproto,
int (*StateGetTxLogged)(void *, void *, uint32_t),
void (*StateSetTxLogged)(void *, void *, uint32_t))
LoggerId (*StateGetTxLogged)(void *, void *),
void (*StateSetTxLogged)(void *, void *, LoggerId))
{
SCEnter();
@ -608,7 +608,7 @@ void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto a
}
void AppLayerParserSetTxLogged(uint8_t ipproto, AppProto alproto,
void *alstate, void *tx, uint32_t logger)
void *alstate, void *tx, LoggerId logger)
{
SCEnter();
@ -621,18 +621,18 @@ void AppLayerParserSetTxLogged(uint8_t ipproto, AppProto alproto,
SCReturn;
}
int AppLayerParserGetTxLogged(const Flow *f,
void *alstate, void *tx, uint32_t logger)
LoggerId AppLayerParserGetTxLogged(const Flow *f,
void *alstate, void *tx)
{
SCEnter();
uint8_t r = 0;
LoggerId r = 0;
if (alp_ctx.ctxs[f->protomap][f->alproto].StateGetTxLogged != NULL) {
r = alp_ctx.ctxs[f->protomap][f->alproto].
StateGetTxLogged(alstate, tx, logger);
StateGetTxLogged(alstate, tx);
}
SCReturnInt(r);
SCReturnUInt(r);
}
uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate)
@ -1225,6 +1225,14 @@ int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto)
SCReturnInt(r);
}
LoggerId AppLayerParserProtocolGetLoggerBits(uint8_t ipproto, AppProto alproto)
{
SCEnter();
const int ipproto_map = FlowGetProtoMapping(ipproto);
LoggerId r = alp_ctx.ctxs[ipproto_map][alproto].logger_bits;
SCReturnUInt(r);
}
void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction)
{
SCEnter();

@ -138,8 +138,8 @@ void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto proto,
void AppLayerParserRegisterHasEventsFunc(uint8_t ipproto, AppProto alproto,
int (*StateHasEvents)(void *));
void AppLayerParserRegisterLoggerFuncs(uint8_t ipproto, AppProto alproto,
int (*StateGetTxLogged)(void *, void *, uint32_t),
void (*StateSetTxLogged)(void *, void *, uint32_t));
LoggerId (*StateGetTxLogged)(void *, void *),
void (*StateSetTxLogged)(void *, void *, LoggerId));
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto);
void AppLayerParserRegisterLoggerBits(uint8_t ipproto, AppProto alproto, LoggerId bits);
void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto,
@ -179,9 +179,8 @@ uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate);
void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id);
void AppLayerParserSetTxLogged(uint8_t ipproto, AppProto alproto, void *alstate,
void *tx, uint32_t logger);
int AppLayerParserGetTxLogged(const Flow *f, void *alstate,
void *tx, uint32_t logger);
void *tx, LoggerId logged);
LoggerId AppLayerParserGetTxLogged(const Flow *f, void *alstate, void *tx);
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction);
void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate,
@ -226,6 +225,7 @@ int AppLayerParserProtocolIsTxAware(uint8_t ipproto, AppProto alproto);
int AppLayerParserProtocolIsTxEventAware(uint8_t ipproto, AppProto alproto);
int AppLayerParserProtocolSupportsTxs(uint8_t ipproto, AppProto alproto);
int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto);
LoggerId AppLayerParserProtocolGetLoggerBits(uint8_t ipproto, AppProto alproto);
void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction);
void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth);
uint32_t AppLayerParserGetStreamDepth(const Flow *f);

@ -44,9 +44,11 @@ typedef struct AppLayerParser {
uint64_t (*StateGetTxCnt)(void *alstate);
void *(*StateGetTx)(void *alstate, uint64_t tx_id);
void (*StateTransactionFree)(void *, uint64_t);
int (*StateGetProgressCompletionStatus)(uint8_t direction);
int (*StateGetProgress)(void *alstate, uint8_t direction);
int (*StateGetTxLogged)(void *alstate, void *tx, uint32_t logger);
uint32_t (*StateGetTxLogged)(void *alstate, void *tx);
void (*StateSetTxLogged)(void *alstate, void *tx, uint32_t logger);
DetectEngineState *(*GetTxDetectState)(void *tx);

@ -1560,19 +1560,16 @@ static void *SMTPStateGetTx(void *state, uint64_t id)
}
static void SMTPStateSetTxLogged(void *state, void *vtx, uint32_t logger)
static void SMTPStateSetTxLogged(void *state, void *vtx, LoggerId logged)
{
SMTPTransaction *tx = vtx;
tx->logged |= logger;
tx->logged = logged;
}
static int SMTPStateGetTxLogged(void *state, void *vtx, uint32_t logger)
static LoggerId SMTPStateGetTxLogged(void *state, void *vtx)
{
SMTPTransaction *tx = vtx;
if (tx->logged & logger)
return 1;
return 0;
return tx->logged;
}
static int SMTPStateGetAlstateProgressCompletionStatus(uint8_t direction) {

@ -543,18 +543,18 @@ static uint64_t SSHGetTxCnt(void *state)
return 1;
}
static void SSHSetTxLogged(void *state, void *tx, uint32_t logger)
static void SSHSetTxLogged(void *state, void *tx, LoggerId logged)
{
SshState *ssh_state = (SshState *)state;
if (ssh_state)
ssh_state->logged |= logger;
ssh_state->logged = logged;
}
static int SSHGetTxLogged(void *state, void *tx, uint32_t logger)
static LoggerId SSHGetTxLogged(void *state, void *tx)
{
SshState *ssh_state = (SshState *)state;
if (ssh_state && (ssh_state->logged & logger)) {
return 1;
if (ssh_state) {
return ssh_state->logged;
}
return 0;
}

@ -198,18 +198,18 @@ static uint64_t SSLGetTxCnt(void *state)
return 1;
}
static void SSLSetTxLogged(void *state, void *tx, uint32_t logger)
static void SSLSetTxLogged(void *state, void *tx, LoggerId logged)
{
SSLState *ssl_state = (SSLState *)state;
if (ssl_state)
ssl_state->logged |= logger;
ssl_state->logged = logged;
}
static int SSLGetTxLogged(void *state, void *tx, uint32_t logger)
static LoggerId SSLGetTxLogged(void *state, void *tx)
{
SSLState *ssl_state = (SSLState *)state;
if (ssl_state && (ssl_state->logged & logger))
return 1;
if (ssl_state)
return (ssl_state->logged);
return 0;
}

@ -377,19 +377,16 @@ static void *TemplateGetTx(void *state, uint64_t tx_id)
return NULL;
}
static void TemplateSetTxLogged(void *state, void *vtx, uint32_t logger)
static void TemplateSetTxLogged(void *state, void *vtx, LoggerId logged)
{
TemplateTransaction *tx = (TemplateTransaction *)vtx;
tx->logged |= logger;
tx->logged = logged;
}
static int TemplateGetTxLogged(void *state, void *vtx, uint32_t logger)
static LoggerId TemplateGetTxLogged(void *state, void *vtx)
{
TemplateTransaction *tx = (TemplateTransaction *)vtx;
if (tx->logged & logger)
return 1;
return 0;
return tx->logged;
}
/**

@ -146,6 +146,9 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data)
goto end;
if (AppLayerParserProtocolHasLogger(p->proto, alproto) == 0)
goto end;
const LoggerId logger_expectation = AppLayerParserProtocolGetLoggerBits(p->proto, alproto);
if (logger_expectation == 0)
goto end;
void *alstate = f->alstate;
if (alstate == NULL) {
@ -163,24 +166,24 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data)
for (; tx_id < total_txs; tx_id++)
{
/* Track the number of loggers, of the eligible loggers that
* actually logged this transaction. They all must have logged
* before the transaction is considered logged. */
int number_of_loggers = 0;
int loggers_that_logged = 0;
void *tx = AppLayerParserGetTx(p->proto, alproto, alstate, tx_id);
if (tx == NULL) {
SCLogDebug("tx is NULL not logging");
continue;
}
LoggerId tx_logged = AppLayerParserGetTxLogged(f, alstate, tx);
const LoggerId tx_logged_old = tx_logged;
SCLogDebug("logger: expect %08x, have %08x", logger_expectation, tx_logged);
if (tx_logged == logger_expectation) {
/* tx already fully logged */
continue;
}
int tx_progress_ts = AppLayerParserGetStateProgress(p->proto, alproto,
tx, ts_disrupt_flags);
int tx_progress_tc = AppLayerParserGetStateProgress(p->proto, alproto,
tx, tc_disrupt_flags);
SCLogDebug("tx_progress_ts %d tx_progress_tc %d",
tx_progress_ts, tx_progress_tc);
@ -197,17 +200,11 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data)
SCLogDebug("logger %p, LogCondition %p, ts_log_progress %d "
"tc_log_progress %d", logger, logger->LogCondition,
logger->ts_log_progress, logger->tc_log_progress);
if (logger->alproto == alproto) {
if (logger->alproto == alproto &&
(tx_logged & (1<<logger->logger_id)) == 0)
{
SCLogDebug("alproto match, logging tx_id %"PRIu64, tx_id);
number_of_loggers++;
if (AppLayerParserGetTxLogged(f, alstate, tx, logger->id)) {
SCLogDebug("logger has already logged this transaction");
loggers_that_logged++;
goto next;
}
if (!(AppLayerParserStateIssetFlag(f->alparser,
APP_LAYER_PARSER_EOF))) {
if (logger->LogCondition) {
@ -235,9 +232,7 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data)
logger->LogFunc(tv, store->thread_data, p, f, alstate, tx, tx_id);
PACKET_PROFILING_LOGGER_END(p, logger->logger_id);
AppLayerParserSetTxLogged(p->proto, alproto, alstate, tx,
logger->id);
loggers_that_logged++;
tx_logged |= (1<<logger->logger_id);
}
next:
@ -249,13 +244,20 @@ next:
#endif
}
if (tx_logged != tx_logged_old) {
SCLogDebug("logger: storing %08x (was %08x)",
tx_logged, tx_logged_old);
AppLayerParserSetTxLogged(p->proto, alproto, alstate, tx,
tx_logged);
}
/* If all loggers logged set a flag and update the last tx_id
* that was logged.
*
* If not all loggers were logged we flag that there was a gap
* so any subsequent transactions in this loop don't increase
* the maximum ID that was logged. */
if (!gap && loggers_that_logged == number_of_loggers) {
if (!gap && tx_logged == logger_expectation) {
logged = 1;
max_id = tx_id;
} else {

Loading…
Cancel
Save