detect/alert: preprocess then append alert queue

Do all alert queue processing before actually appending
the PacketAlerts to the Packet's alert queue.

Task #4943
pull/7349/head
Juliana Fajardini 4 years ago committed by Victor Julien
parent a85340b1ab
commit 185b43edff

@ -279,10 +279,10 @@ typedef uint16_t Port;
* found in this packet */
typedef struct PacketAlert_ {
SigIntId num; /* Internal num, used for sorting */
uint8_t action; /* Internal num, used for sorting */
uint8_t action; /* Internal num, used for thresholding */
uint8_t flags;
const struct Signature_ *s;
uint64_t tx_id;
uint64_t tx_id; /* Used for sorting */
int64_t frame_id;
} PacketAlert;

@ -357,6 +357,23 @@ void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet
return;
}
/** \internal
* \brief sort helper for sorting alerts by priority
*
* Sorting is done first based on num and then using tx_id, if nums are equal.
* The Signature::num field is set based on internal priority. Higher priority
* rules have lower nums.
*/
static int AlertQueueSortHelper(const void *a, const void *b)
{
const PacketAlert *pa0 = a;
const PacketAlert *pa1 = b;
if (pa1->num == pa0->num)
return pa0->tx_id < pa1->tx_id ? 1 : -1;
else
return pa0->num > pa1->num ? 1 : -1;
}
/**
* \brief Check the threshold of the sigs that match, set actions, break on pass action
* This function iterate the packet alerts array, removing those that didn't match
@ -369,13 +386,18 @@ void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet
void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
{
SCEnter();
/* sort the alert queue before thresholding and appending to Packet */
qsort(det_ctx->alert_queue, det_ctx->alert_queue_size, sizeof(PacketAlert),
AlertQueueSortHelper);
int i = 0;
uint16_t max_pos = det_ctx->alert_queue_size;
while (i < p->alerts.cnt) {
const Signature *s = de_ctx->sig_array[p->alerts.alerts[i].num];
SCLogDebug("Sig->num: %" PRIu32 " SID %u", p->alerts.alerts[i].num, s->id);
while (i < max_pos) {
const Signature *s = de_ctx->sig_array[det_ctx->alert_queue[i].num];
uint8_t res = PacketAlertHandle(de_ctx, det_ctx, s, p, &det_ctx->alert_queue[i]);
int res = PacketAlertHandle(de_ctx, det_ctx, s, p, &p->alerts.alerts[i]);
if (res > 0) {
/* Now, if we have an alert, we have to check if we want
* to tag this session or src/dst host */
@ -398,37 +420,36 @@ void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx
* - match is in applayer
* - match is in stream */
if (s->action & (ACTION_DROP | ACTION_PASS)) {
if ((p->alerts.alerts[i].flags &
if ((det_ctx->alert_queue[i].flags &
(PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) ||
(s->flags & (SIG_FLAG_IPONLY | SIG_FLAG_PDONLY | SIG_FLAG_APPLAYER))) {
p->alerts.alerts[i].flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
det_ctx->alert_queue[i].flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "
"PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)",
p->pcap_cnt, s->id, s->action, p->alerts.alerts[i].flags);
p->pcap_cnt, s->id, s->action, det_ctx->alert_queue[i].flags);
}
}
/* set actions on packet */
PacketApplySignatureActions(p, p->alerts.alerts[i].s, p->alerts.alerts[i].flags);
PacketApplySignatureActions(p, s, det_ctx->alert_queue[i].flags);
}
/* Thresholding removes this alert */
if (res == 0 || res == 2 || (s->flags & SIG_FLAG_NOALERT)) {
/* we will not copy this to the AlertQueue */
} else if (p->alerts.cnt < packet_alert_max) {
p->alerts.alerts[p->alerts.cnt] = det_ctx->alert_queue[i];
SCLogDebug("Appending sid %" PRIu32 " alert to Packet::alerts at pos %u", s->id, i);
if (PacketTestAction(p, ACTION_PASS)) {
/* Ok, reset the alert cnt to end in the previous of pass
* so we ignore the rest with less prio */
p->alerts.cnt = i;
break;
}
p->alerts.cnt++;
}
/* Thresholding removes this alert */
if (res == 0 || res == 2 || (s->flags & SIG_FLAG_NOALERT)) {
PacketAlertRemove(p, i);
if (p->alerts.cnt == 0)
break;
} else {
i++;
}
}
/* At this point, we should have all the new alerts. Now check the tag
* keyword context for sessions and hosts */

Loading…
Cancel
Save