suricata
packet-queue.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2019 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 *
23 * Packet Queue portion of the engine.
24 */
25
26#include "suricata-common.h"
27#include "decode.h"
28#include "packet-queue.h"
29#include "threads.h"
30#include "suricata.h"
31#include "util-var.h"
32#include "pkt-var.h"
33#include "util-validate.h"
34
35#ifdef DEBUG
36void PacketQueueValidateDebug(PacketQueue *q);
37void PacketQueueValidate(PacketQueue *q);
38
39void PacketQueueValidateDebug(PacketQueue *q)
40{
41 SCLogDebug("q->len %u, q->top %p, q->bot %p", q->len, q->top, q->bot);
42
43 if (q->len == 0) {
44 BUG_ON(q->top != NULL);
45 BUG_ON(q->bot != NULL);
46 } else if(q->len == 1) {
47 SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev);
48 SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev);
49
50 BUG_ON(q->top != q->bot);
51 BUG_ON(q->top->next != NULL);
52 BUG_ON(q->bot->next != NULL);
53 BUG_ON(q->top->prev != NULL);
54 BUG_ON(q->bot->prev != NULL);
55 } else if (q->len == 2) {
56 SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev);
57 SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev);
58
59 BUG_ON(q->top == NULL);
60 BUG_ON(q->bot == NULL);
61
62 BUG_ON(q->top == q->bot);
63
64 BUG_ON(q->top->prev != NULL);
65 BUG_ON(q->top->next != q->bot);
66
67 BUG_ON(q->bot->prev != q->top);
68 BUG_ON(q->bot->next != NULL);
69 } else {
70 BUG_ON(q->top == NULL);
71 BUG_ON(q->bot == NULL);
72
73 SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev);
74 SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev);
75
76 BUG_ON(q->top == q->bot);
77 BUG_ON(q->top->prev != NULL);
78 BUG_ON(q->bot->next != NULL);
79
80 BUG_ON(q->top->next == q->bot);
81 BUG_ON(q->bot->prev == q->top);
82
83 Packet *p, *pp;
84 for (p = q->top, pp = p->prev; p != NULL; pp = p, p = p->next) {
85 SCLogDebug("p %p, pp %p, p->next %p, p->prev %p", p, pp, p->next, p->prev);
86 BUG_ON(pp != p->prev);
87 }
88
89 }
90}
91
92#define BUGGER_ON(cond) { \
93 if ((cond)) { \
94 PacketQueueValidateDebug(q); \
95 } \
96}
97
98void PacketQueueValidate(PacketQueue *q)
99{
100 if (q->len == 0) {
101 BUGGER_ON(q->top != NULL);
102 BUGGER_ON(q->bot != NULL);
103 } else if(q->len == 1) {
104 BUGGER_ON(q->top != q->bot);
105 BUGGER_ON(q->top->next != NULL);
106 BUGGER_ON(q->bot->next != NULL);
107 BUGGER_ON(q->top->prev != NULL);
108 BUGGER_ON(q->bot->prev != NULL);
109 } else if (q->len == 2) {
110 BUGGER_ON(q->top == NULL);
111 BUGGER_ON(q->bot == NULL);
112
113 BUGGER_ON(q->top == q->bot);
114
115 BUGGER_ON(q->top->prev != NULL);
116 BUGGER_ON(q->top->next != q->bot);
117
118 BUGGER_ON(q->bot->prev != q->top);
119 BUGGER_ON(q->bot->next != NULL);
120 } else {
121 BUGGER_ON(q->top == NULL);
122 BUGGER_ON(q->bot == NULL);
123
124 BUGGER_ON(q->top == q->bot);
125 BUGGER_ON(q->top->prev != NULL);
126 BUGGER_ON(q->bot->next != NULL);
127
128 BUGGER_ON(q->top->next == q->bot);
129 BUGGER_ON(q->bot->prev == q->top);
130
131 Packet *p, *pp;
132 for (p = q->top, pp = p->prev; p != NULL; pp = p, p = p->next) {
133 BUGGER_ON(pp != p->prev);
134 }
135
136 }
137}
138#endif /* DEBUG */
139
140static inline void PacketEnqueueDo(PacketQueue *q, Packet *p)
141{
142 //PacketQueueValidateDebug(q);
143
144 if (p == NULL)
145 return;
146
147 /* more packets in queue */
148 if (q->top != NULL) {
149 p->prev = NULL;
150 p->next = q->top;
151 q->top->prev = p;
152 q->top = p;
153 /* only packet */
154 } else {
155 p->prev = NULL;
156 p->next = NULL;
157 q->top = p;
158 q->bot = p;
159 }
160 q->len++;
161#ifdef DBG_PERF
162 if (q->len > q->dbg_maxlen)
163 q->dbg_maxlen = q->len;
164#endif /* DBG_PERF */
165 //PacketQueueValidateDebug(q);
166}
167
169{
171 PacketQueue *q = (PacketQueue *)qnl;
172 PacketEnqueueDo(q, p);
173}
174
176{
177 PacketEnqueueDo(q, p);
178}
179
180static inline Packet *PacketDequeueDo (PacketQueue *q)
181{
182 //PacketQueueValidateDebug(q);
183 /* if the queue is empty there are no packets left. */
184 if (q->len == 0) {
185 return NULL;
186 }
187 q->len--;
188
189 /* pull the bottom packet from the queue */
190 Packet *p = q->bot;
191
192 /* more packets in queue */
193 if (q->bot->prev != NULL) {
194 q->bot = q->bot->prev;
195 q->bot->next = NULL;
196 /* just the one we remove, so now empty */
197 } else {
198 q->top = NULL;
199 q->bot = NULL;
200 }
201
202 //PacketQueueValidateDebug(q);
203 p->next = NULL;
204 p->prev = NULL;
205 return p;
206}
207
209{
210 PacketQueue *q = (PacketQueue *)qnl;
211 Packet *p = PacketDequeueDo(q);
212 DEBUG_VALIDATE_BUG_ON(p != NULL && p->pkt_src == 0);
213 return p;
214}
215
217{
218 return PacketDequeueDo(q);
219}
220
222{
223 PacketQueue *pq = SCCalloc(1, sizeof(*pq));
224 if (pq == NULL)
225 return NULL;
226 SCMutexInit(&pq->mutex_q, NULL);
227 SCCondInit(&pq->cond_q, NULL);
228 return pq;
229}
230
232{
233 SCCondDestroy(&pq->cond_q);
235 SCFree(pq);
236}
void PacketEnqueue(PacketQueue *q, Packet *p)
PacketQueue * PacketQueueAlloc(void)
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
void PacketQueueFree(PacketQueue *pq)
Packet * PacketDequeue(PacketQueue *q)
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
simple fifo queue for packets
simple fifo queue for packets with mutex and cond Calling the mutex or triggering the cond is respons...
uint32_t len
SCMutex mutex_q
struct Packet_ * bot
struct Packet_ * top
SCCondT cond_q
uint8_t pkt_src
Definition decode.h:611
struct Packet_ * next
Definition decode.h:635
struct Packet_ * prev
Definition decode.h:636
#define BUG_ON(x)
#define SCCondInit
#define SCMutexDestroy
#define SCMutexInit(mut, mutattrs)
#define SCCondDestroy
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define DEBUG_VALIDATE_BUG_ON(exp)