suricata 数据包队列遵循先进先出的方式。包队列结构体如下:
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数据包队列中元素为包(packet),包由双向链表结构组成,入队时,把新数据包压入队列头部(top),并修改数据包的前向指针和后向指针指向的位置。最后把队头指针指向新数据包。
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 数据包出队时由队尾出来并修改队尾指针bot。
网友评论