From: Victor Julien Date: Wed, 23 Mar 2016 15:16:41 +0000 (+0100) Subject: detect reload: call 'breakloop' on capture method X-Git-Tag: suricata-3.0.1~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eafd212661afbb57e07d237e7207ced2a44b5eee;p=thirdparty%2Fsuricata.git detect reload: call 'breakloop' on capture method Split wait loop into three steps: - first insert pseudo packets - 2nd nudge all capture threads to break out of their loop - third, wait for the detection thread contexts to be used Interupt capture more than once if needed Move packet injection into util func --- diff --git a/src/detect-engine.c b/src/detect-engine.c index 492f2f1087..7535938260 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -541,6 +541,63 @@ int DetectEngineReloadIsDone(void) return r; } +/* nudge capture loops to wake up */ +static void BreakCapture(void) +{ + SCMutexLock(&tv_root_lock); + ThreadVars *tv = tv_root[TVT_PPT]; + while (tv) { + /* find the correct slot */ + TmSlot *slots = tv->tm_slots; + while (slots != NULL) { + if (suricata_ctl_flags != 0) { + return; + } + + TmModule *tm = TmModuleGetById(slots->tm_id); + if (!(tm->flags & TM_FLAG_RECEIVE_TM)) { + slots = slots->slot_next; + continue; + } + + if (tm->PktAcqLoop && tm->PktAcqBreakLoop) { + tm->PktAcqBreakLoop(tv, SC_ATOMIC_GET(slots->slot_data)); + } + break; + } + tv = tv->next; + } + SCMutexUnlock(&tv_root_lock); +} + +/** \internal + * \brief inject a pseudo packet into each detect thread that doesn't use the + * new det_ctx yet + */ +static void InjectPackets(ThreadVars **detect_tvs, + DetectEngineThreadCtx **new_det_ctx, + int no_of_detect_tvs) +{ + int i; + /* inject a fake packet if the detect thread isn't using the new ctx yet, + * this speeds up the process */ + for (i = 0; i < no_of_detect_tvs; i++) { + if (SC_ATOMIC_GET(new_det_ctx[i]->so_far_used_by_detect) != 1) { + if (detect_tvs[i]->inq != NULL) { + Packet *p = PacketGetFromAlloc(); + if (p != NULL) { + p->flags |= PKT_PSEUDO_STREAM_END; + PacketQueue *q = &trans_q[detect_tvs[i]->inq->id]; + SCMutexLock(&q->mutex_q); + PacketEnqueue(q, p); + SCCondSignal(&q->cond_q); + SCMutexUnlock(&q->mutex_q); + } + } + } + } +} + /** \internal * \brief Update detect threads with new detect engine * @@ -675,11 +732,10 @@ static int DetectEngineReloadThreads(DetectEngineCtx *new_de_ctx) SCLogInfo("Live rule swap has swapped %d old det_ctx's with new ones, " "along with the new de_ctx", no_of_detect_tvs); - /* inject a fake packet if the detect thread isn't using the new ctx yet, - * this speeds up the process */ + InjectPackets(detect_tvs, new_det_ctx, no_of_detect_tvs); + for (i = 0; i < no_of_detect_tvs; i++) { int break_out = 0; - int pseudo_pkt_inserted = 0; usleep(1000); while (SC_ATOMIC_GET(new_det_ctx[i]->so_far_used_by_detect) != 1) { if (suricata_ctl_flags != 0) { @@ -687,20 +743,7 @@ static int DetectEngineReloadThreads(DetectEngineCtx *new_de_ctx) break; } - if (pseudo_pkt_inserted == 0) { - pseudo_pkt_inserted = 1; - if (detect_tvs[i]->inq != NULL) { - Packet *p = PacketGetFromAlloc(); - if (p != NULL) { - p->flags |= PKT_PSEUDO_STREAM_END; - PacketQueue *q = &trans_q[detect_tvs[i]->inq->id]; - SCMutexLock(&q->mutex_q); - PacketEnqueue(q, p); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); - } - } - } + BreakCapture(); usleep(1000); } if (break_out)