/* check if the 'check' timestamp is not before the creation ts.
* This can happen due to the async nature of the host timeout
* code that also calls this code from a management thread. */
- if (((uint32_t)tv->tv_sec < tmp->tv_sec1) || (tv->tv_sec - tmp->tv_sec1) <= tmp->seconds) {
+ if (TIMEVAL_EARLIER(*tv, tmp->tv1) || TIMEVAL_DIFF_SEC(*tv, tmp->tv1) <= tmp->seconds) {
prev = tmp;
tmp = tmp->next;
continue;
* \retval int 1 if threshold reached for this entry
*
*/
-static int IsThresholdReached(DetectThresholdEntry* lookup_tsh, const DetectThresholdData *td, uint32_t packet_time)
+static int IsThresholdReached(DetectThresholdEntry* lookup_tsh, const DetectThresholdData *td, struct timeval packet_time)
{
int ret = 0;
/* Check if we have a timeout enabled, if so,
* we still matching (and enabling the new_action) */
if (lookup_tsh->tv_timeout != 0) {
- if ((packet_time - lookup_tsh->tv_timeout) > td->timeout) {
+ if ((packet_time.tv_sec - lookup_tsh->tv_timeout) > td->timeout) {
/* Ok, we are done, timeout reached */
lookup_tsh->tv_timeout = 0;
}
}
else {
/* Update the matching state with the timeout interval */
- if ((packet_time - lookup_tsh->tv_sec1) < td->seconds) {
+ if (TIMEVAL_DIFF_SEC(packet_time, lookup_tsh->tv1) < 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 = packet_time;
+ lookup_tsh->tv_timeout = packet_time.tv_sec;
ret = 1;
}
}
else {
- lookup_tsh->tv_sec1 = packet_time;
+ lookup_tsh->tv1 = packet_time;
lookup_tsh->current_count = 1;
}
} /* else - if (lookup_tsh->tv_timeout != 0) */
return ret;
}
-static void AddEntryToHostStorage(Host *h, DetectThresholdEntry *e, uint32_t packet_time)
+static void AddEntryToHostStorage(Host *h, DetectThresholdEntry *e, struct timeval packet_time)
{
if (h && e) {
e->current_count = 1;
- e->tv_sec1 = packet_time;
+ e->tv1 = packet_time;
e->tv_timeout = 0;
e->next = HostGetStorageById(h, host_threshold_id);
HostSetStorageById(h, host_threshold_id, e);
}
}
-static void AddEntryToIPPairStorage(IPPair *pair, DetectThresholdEntry *e, uint32_t packet_time)
+static void AddEntryToIPPairStorage(IPPair *pair, DetectThresholdEntry *e, struct timeval packet_time)
{
if (pair && e) {
e->current_count = 1;
- e->tv_sec1 = packet_time;
+ e->tv1 = packet_time;
e->tv_timeout = 0;
e->next = IPPairGetStorageById(pair, ippair_threshold_id);
IPPairSetStorageById(pair, ippair_threshold_id, e);
}
}
-static int ThresholdHandlePacketIPPair(IPPair *pair, Packet *p, const DetectThresholdData *td,
- uint32_t sid, uint32_t gid, PacketAlert *pa)
-{
- int ret = 0;
-
- DetectThresholdEntry *lookup_tsh = ThresholdIPPairLookupEntry(pair, sid, gid);
- SCLogDebug("ippair lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);
-
- switch (td->type) {
- case TYPE_RATE:
- {
- SCLogDebug("rate_filter");
- ret = 1;
- if (lookup_tsh && IsThresholdReached(lookup_tsh, td, p->ts.tv_sec)) {
- RateFilterSetAction(p, pa, td->new_action);
- } else if (!lookup_tsh) {
- DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
- AddEntryToIPPairStorage(pair, e, p->ts.tv_sec);
- }
- break;
- }
- default:
- {
- SCLogError(SC_ERR_INVALID_VALUE, "type %d is not supported", td->type);
- break;
- }
- }
-
- return ret;
-}
-
/**
* \retval 2 silent match (no alert but apply actions)
* \retval 1 normal match
* \retval 0 no match
+ *
+ * If a new DetectThresholdEntry is generated to track the threshold
+ * for this rule, then it will be returned in new_tsh.
*/
-static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdData *td,
+static int ThresholdHandlePacket(Packet *p, DetectThresholdEntry *lookup_tsh,
+ DetectThresholdEntry **new_tsh, const DetectThresholdData *td,
uint32_t sid, uint32_t gid, PacketAlert *pa)
{
int ret = 0;
- DetectThresholdEntry *lookup_tsh = ThresholdHostLookupEntry(h, sid, gid);
- SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);
-
switch(td->type) {
case TYPE_LIMIT:
{
SCLogDebug("limit");
if (lookup_tsh != NULL) {
- if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
+ if (TIMEVAL_DIFF_SEC(p->ts, lookup_tsh->tv1) < td->seconds) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count <= td->count) {
ret = 2;
}
} else {
- lookup_tsh->tv_sec1 = p->ts.tv_sec;
+ lookup_tsh->tv1 = p->ts;
lookup_tsh->current_count = 1;
ret = 1;
}
} else {
- DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
- if (e == NULL) {
- break;
- }
-
- e->tv_sec1 = p->ts.tv_sec;
- e->current_count = 1;
+ *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
ret = 1;
-
- e->next = HostGetStorageById(h, host_threshold_id);
- HostSetStorageById(h, host_threshold_id, e);
}
break;
}
SCLogDebug("threshold");
if (lookup_tsh != NULL) {
- if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
+ if (TIMEVAL_DIFF_SEC(p->ts, lookup_tsh->tv1) < td->seconds) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count >= td->count) {
lookup_tsh->current_count = 0;
}
} else {
- lookup_tsh->tv_sec1 = p->ts.tv_sec;
+ lookup_tsh->tv1 = p->ts;
lookup_tsh->current_count = 1;
}
} else {
if (td->count == 1) {
ret = 1;
} else {
- DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
- if (e == NULL) {
- break;
- }
-
- e->current_count = 1;
- e->tv_sec1 = p->ts.tv_sec;
-
- e->next = HostGetStorageById(h, host_threshold_id);
- HostSetStorageById(h, host_threshold_id, e);
+ *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
}
}
break;
SCLogDebug("both");
if (lookup_tsh != NULL) {
- if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) {
+ if (TIMEVAL_DIFF_SEC(p->ts, lookup_tsh->tv1) < td->seconds) {
/* within time limit */
lookup_tsh->current_count++;
}
} else {
/* expired, so reset */
- lookup_tsh->tv_sec1 = p->ts.tv_sec;
+ lookup_tsh->tv1 = p->ts;
lookup_tsh->current_count = 1;
/* if we have a limit of 1, this is a match */
}
}
} else {
- DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
- if (e == NULL) {
- break;
- }
-
- e->current_count = 1;
- e->tv_sec1 = p->ts.tv_sec;
-
- e->next = HostGetStorageById(h, host_threshold_id);
- HostSetStorageById(h, host_threshold_id, e);
+ *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
/* for the first match we return 1 to
* indicate we should alert */
SCLogDebug("detection_filter");
if (lookup_tsh != NULL) {
- long double time_diff = ((p->ts.tv_sec + p->ts.tv_usec/1000000.0) -
- (lookup_tsh->tv_sec1 + lookup_tsh->tv_usec1/1000000.0));
-
- if (time_diff < td->seconds) {
+ if (TIMEVAL_DIFF_SEC(p->ts, lookup_tsh->tv1) < td->seconds) {
/* within timeout */
-
lookup_tsh->current_count++;
if (lookup_tsh->current_count > td->count) {
ret = 1;
}
} else {
/* expired, reset */
-
- lookup_tsh->tv_sec1 = p->ts.tv_sec;
- lookup_tsh->tv_usec1 = p->ts.tv_usec;
+ lookup_tsh->tv1 = p->ts;
lookup_tsh->current_count = 1;
}
} else {
- DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
- if (e == NULL) {
- break;
- }
-
- e->current_count = 1;
- e->tv_sec1 = p->ts.tv_sec;
- e->tv_usec1 = p->ts.tv_usec;
-
- e->next = HostGetStorageById(h, host_threshold_id);
- HostSetStorageById(h, host_threshold_id, e);
+ *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
}
break;
}
{
SCLogDebug("rate_filter");
ret = 1;
- if (lookup_tsh && IsThresholdReached(lookup_tsh, td, p->ts.tv_sec)) {
+ if (lookup_tsh && IsThresholdReached(lookup_tsh, td, p->ts)) {
RateFilterSetAction(p, pa, td->new_action);
} else if (!lookup_tsh) {
- DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid);
- AddEntryToHostStorage(h, e, p->ts.tv_sec);
+ *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
}
break;
}
default:
SCLogError(SC_ERR_INVALID_VALUE, "type %d is not supported", td->type);
}
+ return ret;
+}
+
+static int ThresholdHandlePacketIPPair(IPPair *pair, Packet *p, const DetectThresholdData *td,
+ uint32_t sid, uint32_t gid, PacketAlert *pa)
+{
+ int ret = 0;
+
+ DetectThresholdEntry *lookup_tsh = ThresholdIPPairLookupEntry(pair, sid, gid);
+ SCLogDebug("ippair lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);
+
+ DetectThresholdEntry *new_tsh = NULL;
+ ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, sid, gid, pa);
+ if (new_tsh != NULL) {
+ AddEntryToIPPairStorage(pair, new_tsh, p->ts);
+ }
+
+ return ret;
+}
+
+/**
+ * \retval 2 silent match (no alert but apply actions)
+ * \retval 1 normal match
+ * \retval 0 no match
+ */
+static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdData *td,
+ uint32_t sid, uint32_t gid, PacketAlert *pa)
+{
+ int ret = 0;
+ DetectThresholdEntry *lookup_tsh = ThresholdHostLookupEntry(h, sid, gid);
+ SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);
+ DetectThresholdEntry *new_tsh = NULL;
+ ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, sid, gid, pa);
+ if (new_tsh != NULL) {
+ AddEntryToHostStorage(h, new_tsh, p->ts);
+ }
return ret;
}
DetectThresholdEntry* lookup_tsh = (DetectThresholdEntry *)de_ctx->ths_ctx.th_entry[s->num];
SCLogDebug("by_rule lookup_tsh %p num %u", lookup_tsh, s->num);
- 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);
- }
- 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;
- }
- }
- break;
- }
- default:
- {
- SCLogError(SC_ERR_INVALID_VALUE, "type %d is not supported", td->type);
- break;
- }
+ DetectThresholdEntry *new_tsh = NULL;
+ ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, s->id, s->gid, pa);
+ if (new_tsh != NULL) {
+ new_tsh->tv1 = p->ts;
+ new_tsh->current_count = 1;
+ new_tsh->tv_timeout = 0;
+ de_ctx->ths_ctx.th_entry[s->num] = new_tsh;
}
return ret;