进一步的数据包处理是在TmThreadsSlotProcessPkt中完成,其原型为:
static inline TmEcode TmThreadsSlotProcessPkt(ThreadVars *tv, TmSlot *s, Packet *p)
其中,s就是前面一路传下来的slot,而p为当前要处理的Packet。
/**
* \brief Process the rest of the functions (if any) and queue.
*/
static inline TmEcode TmThreadsSlotProcessPkt(ThreadVars *tv, TmSlot *s, Packet *p)
{
TmEcode r = TM_ECODE_OK;
if (s == NULL) {
tv->tmqh_out(tv, p);
return r;
}
if (TmThreadsSlotVarRun(tv, p, s) == TM_ECODE_FAILED) {
TmqhOutputPacketpool(tv, p);
TmSlot *slot = s;
while (slot != NULL) {
SCMutexLock(&slot->slot_post_pq.mutex_q);
TmqhReleasePacketsToPacketPool(&slot->slot_post_pq);
SCMutexUnlock(&slot->slot_post_pq.mutex_q);
slot = slot->slot_next;
}
TmThreadsSetFlag(tv, THV_FAILED);
r = TM_ECODE_FAILED;
/*调用TmThreadsSlotVarRun,将数据包依次传入后续的各个slot进行处理,若返回失败,
则调用TmqhOutputPacketpool将数据包(以及各个slot的slot_post_pq中的数据包)进行
回收或释放。然后设置线程标志为THV_FAILED,等待主线程处理*/
} else {
tv->tmqh_out(tv, p);
/*若返回成功,则调用tmqh_out(线程创建时设置为与该线程绑定的outqh的处理函数OutHandler,
在这里默认为TmqhOutputFlowHash),将数据包送到后续队列中去。在这里会通过队列交给
FlowWorker线程来处理。*/
/* post process pq */
TmSlot *slot = s;
while (slot != NULL) {
if (slot->slot_post_pq.top != NULL) {
while (1) {
SCMutexLock(&slot->slot_post_pq.mutex_q);
Packet *extra_p = PacketDequeue(&slot->slot_post_pq);
SCMutexUnlock(&slot->slot_post_pq.mutex_q);
if (extra_p == NULL)
break;
if (slot->slot_next != NULL) {
r = TmThreadsSlotVarRun(tv, extra_p, slot->slot_next);
if (r == TM_ECODE_FAILED) {
SCMutexLock(&slot->slot_post_pq.mutex_q);
TmqhReleasePacketsToPacketPool(&slot->slot_post_pq);
SCMutexUnlock(&slot->slot_post_pq.mutex_q);
TmqhOutputPacketpool(tv, extra_p);
TmThreadsSetFlag(tv, THV_FAILED);
break;
}
}
tv->tmqh_out(tv, extra_p);
}
} /* if (slot->slot_post_pq.top != NULL) */
/*此外,由于各模块在处理过程中可能会新生成数据包(如隧道数据包、重组数据包),这些数据包存
储在与每个slot绑定的slot_pre_pq或slot_post_pq队列中,因此还需要类似上述流程,对这些数据包
进行处理。这里只集中处理了slot_post_pq,slot_pre_pq将在处理每个slot后立即处理*/
slot = slot->slot_next;
} /* while (slot != NULL) */
}
return r;
}