suricata 數(shù)據(jù)包隊列遵循先進(jìn)先出的方式。包隊列結(jié)構(gòu)體如下:
typedef struct PacketQueue_ {
? ? Packet *top;
? ? Packet *bot;
? ? uint32_t len;
#ifdef DBG_PERF
? ? uint32_t dbg_maxlen;
#endif /* DBG_PERF */
? ? SCMutex mutex_q;
? ? SCCondT cond_q;
} PacketQueue;
1.入隊
void PacketEnqueue (PacketQueue *q, Packet *p)
{
? ? //PacketQueueValidateDebug(q);
? ? if (p == NULL)
? ? ? ? return;
? ? /* more packets in queue */
? ? if (q->top != NULL) {
? ? ? ? p->prev = NULL;
? ? ? ? p->next = q->top;
? ? ? ? q->top->prev = p;
? ? ? ? q->top = p;
? ? /* only packet */
? ? } else {
? ? ? ? p->prev = NULL;
? ? ? ? p->next = NULL;
? ? ? ? q->top = p;
? ? ? ? q->bot = p;
? ? }
? ? q->len++;
#ifdef DBG_PERF
? ? if (q->len > q->dbg_maxlen)
? ? ? ? q->dbg_maxlen = q->len;
#endif /* DBG_PERF */
? ? //PacketQueueValidateDebug(q);
}
suricata數(shù)據(jù)包隊列中元素為包(packet),包由雙向鏈表結(jié)構(gòu)組成,入隊時,把新數(shù)據(jù)包壓入隊列頭部(top),并修改數(shù)據(jù)包的前向指針和后向指針指向的位置。最后把隊頭指針指向新數(shù)據(jù)包。

2.出隊
Packet *PacketDequeue (PacketQueue *q)
{
? ? Packet *p = NULL;
? ? //PacketQueueValidateDebug(q);
? ? /* if the queue is empty there are no packets left. */
? ? if (q->len == 0) {
? ? ? ? return NULL;
? ? }
? ? q->len--;
? ? /* pull the bottom packet from the queue */
? ? p = q->bot;
? ? /* Weird issue: sometimes it looks that two thread arrive
? ? * here at the same time so the bot ptr is NULL (only on OS X?)
? ? */
? ? BUG_ON (p == NULL);
? ? /* more packets in queue */
? ? if (q->bot->prev != NULL) {
? ? ? ? q->bot = q->bot->prev;
? ? ? ? q->bot->next = NULL;
? ? ? ? /* just the one we remove, so now empty */
? ? } else {
? ? ? ? q->top = NULL;
? ? ? ? q->bot = NULL;
? ? }
? ? //PacketQueueValidateDebug(q);
? ? p->next = NULL;
? ? p->prev = NULL;
? ? return p;
}
suricata 數(shù)據(jù)包出隊時由隊尾出來并修改隊尾指針bot。
