if (unlikely(ste == NULL)) {
SCReturnPtr(NULL, "DetectThresholdEntry");
}
+ memset(ste, 0, sizeof(*ste));
ste->sid = sid;
ste->gid = gid;
ste->track = td->track;
ste->seconds = td->seconds;
- ste->tv_timeout = 0;
SCReturnPtr(ste, "DetectThresholdEntry");
}
{
int ret = 0;
- if (td->type != TYPE_RATE)
- return 1;
-
DetectThresholdEntry* lookup_tsh = (DetectThresholdEntry *)de_ctx->ths_ctx.th_entry[s->num];
- if (lookup_tsh != NULL) {
- /* Check if we have a timeout enabled, if so,
- * we still matching (and enabling the new_action) */
- if ( (p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) {
- /* Ok, we are done, timeout reached */
- lookup_tsh->tv_timeout = 0;
- } else {
- /* Already matching */
- /* Take the action to perform */
- RateFilterSetAction(p, pa, td->new_action);
- ret = 1;
- }
+ SCLogDebug("by_rule lookup_tsh %p num %u", lookup_tsh, s->num);
- /* Update the matching state with the timeout interval */
- if ( (p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
- lookup_tsh->current_count++;
- if (lookup_tsh->current_count >= td->count) {
- /* Then we must enable the new action by setting a
- * timeout */
- lookup_tsh->tv_timeout = p->ts.tv_sec;
- /* Take the action to perform */
+ switch (td->type) {
+ case TYPE_RATE:
+ {
+ ret = 1;
+ if (lookup_tsh && IsThresholdReached(lookup_tsh, td, p->ts.tv_sec)) {
RateFilterSetAction(p, pa, td->new_action);
- ret = 1;
}
- } else {
- lookup_tsh->tv_sec1 = p->ts.tv_sec;
- lookup_tsh->current_count = 1;
- }
- } else {
- if (td->count == 1) {
- ret = 1;
- }
-
- DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, s->id, s->gid);
- if (e != NULL) {
- e->current_count = 1;
- e->tv_sec1 = p->ts.tv_sec;
- e->tv_timeout = 0;
+ else if (!lookup_tsh) {
+ DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, s->id, s->gid);
+ if (e != NULL) {
+ e->current_count = 1;
+ e->tv_sec1 = p->ts.tv_sec;
+ e->tv_timeout = 0;
- de_ctx->ths_ctx.th_entry[s->num] = e;
+ de_ctx->ths_ctx.th_entry[s->num] = e;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ SCLogError(SC_ERR_INVALID_VALUE, "type %d is not supported", td->type);
+ break;
}
}
}
/**
- * \brief Creates a dummy threshold file, with all valid options, but
- * with splitted rules (multiline), for testing purposes.
+ * \brief Creates a dummy threshold file, for testing rate_filter, track by_rule
*
* \retval fd Pointer to file descriptor.
*/
{
FILE *fd = NULL;
const char *buffer =
- "rate_filter gen_id 1, sig_id 10, track by_rule, count 3, seconds 3, new_action drop, timeout 10\n"
- "rate_filter gen_id 1, sig_id 11, track by_src, count 3, seconds 1, new_action drop, timeout 5\n";
+ "rate_filter gen_id 1, sig_id 10, track by_rule, count 3, seconds 3, new_action drop, timeout 10\n";
fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
if (fd == NULL)
memset (&ts, 0, sizeof(struct timeval));
TimeGet(&ts);
- Packet *p1 = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP);
+ /* Create two different packets falling to the same rule, and
+ * because count:3, we should drop on match #4.
+ */
+ Packet *p1 = UTHBuildPacketSrcDst((uint8_t*)"lalala", 6, IPPROTO_TCP,
+ "172.26.0.2", "172.26.0.11");
FAIL_IF_NULL(p1);
Packet *p2 = UTHBuildPacketSrcDst((uint8_t*)"lalala", 6, IPPROTO_TCP,
"172.26.0.1", "172.26.0.10");
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
TimeGet(&p1->ts);
+ p2->ts = p1->ts;
+ /* All should be alerted, none dropped */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
- FAIL_IF(PacketAlertCheck(p1, 10));
+ FAIL_IF(PACKET_TEST_ACTION(p1, ACTION_DROP));
+ FAIL_IF(PacketAlertCheck(p1, 10) != 1);
+ p1->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
- FAIL_IF(PacketAlertCheck(p2, 10));
-
+ FAIL_IF(PACKET_TEST_ACTION(p2, ACTION_DROP));
+ FAIL_IF(PacketAlertCheck(p2, 10) != 1);
+ p2->action = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
- FAIL_IF_NOT(PacketAlertCheck(p1, 10) == 1);
+ FAIL_IF(PACKET_TEST_ACTION(p1, ACTION_DROP));
+ FAIL_IF(PacketAlertCheck(p1, 10) != 1);
+ p1->action = 0;
+
+ /* Match #4 should be dropped*/
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+ FAIL_IF_NOT(PACKET_TEST_ACTION(p2, ACTION_DROP));
+ FAIL_IF(PacketAlertCheck(p2, 10) != 1);
+ p2->action = 0;
TimeSetIncrementTime(2);
TimeGet(&p1->ts);
- SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
- FAIL_IF_NOT(PacketAlertCheck(p2, 10) == 1);
+ /* Still dropped because timeout not expired */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+ FAIL_IF_NOT(PACKET_TEST_ACTION(p1, ACTION_DROP));
+ FAIL_IF(PacketAlertCheck(p1, 10) != 1);
+ p1->action = 0;
TimeSetIncrementTime(10);
TimeGet(&p1->ts);
+ /* Not dropped because timeout expired */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
- FAIL_IF_NOT(PacketAlertCheck(p1, 10) == 0);
+ FAIL_IF(PACKET_TEST_ACTION(p1, ACTION_DROP));
+ FAIL_IF(PacketAlertCheck(p1, 10) != 1);
/* Ensure that a Threshold entry was installed at the sig */
FAIL_IF_NULL(de_ctx->ths_ctx.th_entry[s->num]);