AppLayerDecoderEvents *DNSGetEvents(void *state, uint64_t id) {
DNSState *dns_state = (DNSState *)state;
DNSTransaction *tx;
+
+ if (dns_state->curr && dns_state->curr->tx_num == (id + 1)) {
+ return dns_state->curr->decoder_events;
+ }
+
TAILQ_FOREACH(tx, &dns_state->tx_list, next) {
if (tx->tx_num == (id+1))
return tx->decoder_events;
return NULL;
}
+int DNSHasEvents(void *state) {
+ DNSState *dns_state = (DNSState *)state;
+ return (dns_state->events > 0);
+}
+
void *DNSStateAlloc(void) {
void *s = SCMalloc(sizeof(DNSState));
if (unlikely(s == NULL))
DNSState *dns_state = (DNSState *)alstate;
DNSTransaction *tx = NULL;
+ if (dns_state->curr && dns_state->curr->tx_num == tx_id + 1)
+ return dns_state->curr;
+
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)
SCLogDebug("s->curr->decoder_events %p", s->curr->decoder_events);
AppLayerDecoderEventsSetEventRaw(s->curr->decoder_events, e);
SCLogDebug("s->curr->decoder_events %p", s->curr->decoder_events);
+ s->events++;
} else {
SCLogDebug("couldn't set event %u", e);
}
TAILQ_HEAD(, DNSTransaction_) tx_list; /**< transaction list */
DNSTransaction *curr; /**< ptr to current tx */
uint16_t transaction_max;
- uint16_t transaction_done;
+ uint16_t events;
/* used by TCP only */
uint16_t offset;
void *DNSStateAlloc(void);
void DNSStateFree(void *s);
AppLayerDecoderEvents *DNSGetEvents(void *state, uint64_t id);
+int DNSHasEvents(void *state);
int DNSValidateRequestHeader(DNSState *, const DNSHeader *dns_header);
int DNSValidateResponseHeader(DNSState *, const DNSHeader *dns_header);
DNSState *s = state;
- s->transaction_done = id;
SCLogDebug("state %p, id %"PRIu16, s, id);
/* we can't remove the actual transactions here */
DNSStateFree);
AppLayerRegisterTransactionIdFuncs(ALPROTO_DNS_TCP,
DNSStateUpdateTransactionId, DNSStateTransactionFree);
+
AppLayerRegisterGetEventsFunc(ALPROTO_DNS_TCP, DNSGetEvents);
+ AppLayerRegisterHasEventsFunc(ALPROTO_DNS_TCP, DNSHasEvents);
AppLayerRegisterGetTx(ALPROTO_DNS_TCP,
DNSGetTx);
DNSState *s = state;
- s->transaction_done = id;
SCLogDebug("state %p, id %"PRIu16, s, id);
/* we can't remove the actual transactions here */
DNSStateFree);
AppLayerRegisterTransactionIdFuncs(ALPROTO_DNS_UDP,
DNSStateUpdateTransactionId, DNSStateTransactionFree);
+
AppLayerRegisterGetEventsFunc(ALPROTO_DNS_UDP, DNSGetEvents);
+ AppLayerRegisterHasEventsFunc(ALPROTO_DNS_UDP, DNSHasEvents);
AppLayerRegisterGetTx(ALPROTO_DNS_UDP,
DNSGetTx);
}
}
-/** \brief check if we have decoder events */
+/** \brief check if we have decoder events
+ * \retval 1 yes
+ * \retval 0 no */
int AppLayerFlowHasDecoderEvents(Flow *f, uint8_t flags) {
AppLayerDecoderEvents *decoder_events;
- uint64_t tx_id, max_id;
DEBUG_ASSERT_FLOW_LOCKED(f);
return 0;
if (AppLayerProtoIsTxEventAware(f->alproto)) {
- tx_id = AppLayerTransactionGetInspectId(f, flags);
- max_id = AppLayerGetTxCnt(f->alproto, f->alstate);
-
- for ( ; tx_id < max_id; tx_id++) {
- decoder_events = AppLayerGetEventsFromFlowByTx(f, tx_id);
- if (decoder_events && decoder_events->cnt)
+ /* fast path if supported by proto */
+ if (al_proto_table[f->alproto].StateHasEvents != NULL) {
+ if (al_proto_table[f->alproto].StateHasEvents(f->alstate) == 1)
return 1;
+ } else {
+ /* check each tx */
+ uint64_t tx_id = AppLayerTransactionGetInspectId(f, flags);
+ uint64_t max_id = AppLayerGetTxCnt(f->alproto, f->alstate);
+
+ for ( ; tx_id < max_id; tx_id++) {
+ decoder_events = AppLayerGetEventsFromFlowByTx(f, tx_id);
+ if (decoder_events && decoder_events->cnt)
+ return 1;
+ }
}
}
al_proto_table[proto].StateGetEvents = StateGetEvents;
}
+void AppLayerRegisterHasEventsFunc(uint16_t proto,
+ int (*StateHasEvents)(void *)) {
+ al_proto_table[proto].StateHasEvents = StateHasEvents;
+}
+
/** \brief Indicate to the app layer parser that a logger is active
* for this protocol.
*/
void (*Truncate)(void *, uint8_t);
FileContainer *(*StateGetFiles)(void *, uint8_t);
AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t);
+ /* bool indicating a state has decoder/parser events */
+ int (*StateHasEvents)(void *);
int (*StateGetAlstateProgress)(void *alstate, uint8_t direction);
uint64_t (*StateGetTxCnt)(void *alstate);
FileContainer *(*StateGetFile)(void *, uint8_t));
void AppLayerRegisterGetEventsFunc(uint16_t proto,
AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t));
+void AppLayerRegisterHasEventsFunc(uint16_t proto,
+ int (*StateHasEvents)(void *));
+
void AppLayerRegisterLogger(uint16_t proto);
uint16_t AppLayerGetProtoByName(const char *);
const char *AppLayerGetProtoString(int proto);