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
36 void PacketQueueValidateDebug(PacketQueue *q);
37 void PacketQueueValidate(PacketQueue *q);
38 
39 void 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 
98 void 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 
140 static 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 
180 static 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);
234  SCMutexDestroy(&pq->mutex_q);
235  SCFree(pq);
236 }
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
PacketEnqueue
void PacketEnqueue(PacketQueue *q, Packet *p)
Definition: packet-queue.c:175
PacketQueue_
simple fifo queue for packets with mutex and cond Calling the mutex or triggering the cond is respons...
Definition: packet-queue.h:49
threads.h
SCCondInit
#define SCCondInit
Definition: threads-debug.h:138
packet-queue.h
util-var.h
PacketQueueNoLock_
simple fifo queue for packets
Definition: packet-queue.h:34
PacketQueue_::mutex_q
SCMutex mutex_q
Definition: packet-queue.h:56
decode.h
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:208
Packet_::prev
struct Packet_ * prev
Definition: decode.h:602
pkt-var.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
Packet_
Definition: decode.h:473
PacketQueue_::bot
struct Packet_ * bot
Definition: packet-queue.h:51
PacketQueue_::cond_q
SCCondT cond_q
Definition: packet-queue.h:57
SCMutexInit
#define SCMutexInit(mut, mutattrs)
Definition: threads-debug.h:116
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:168
suricata-common.h
PacketQueue_::len
uint32_t len
Definition: packet-queue.h:52
PacketDequeue
Packet * PacketDequeue(PacketQueue *q)
Definition: packet-queue.c:216
util-validate.h
Packet_::next
struct Packet_ * next
Definition: decode.h:601
PacketQueue_::top
struct Packet_ * top
Definition: packet-queue.h:50
SCCondDestroy
#define SCCondDestroy
Definition: threads-debug.h:140
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Packet_::pkt_src
uint8_t pkt_src
Definition: decode.h:577
PacketQueueAlloc
PacketQueue * PacketQueueAlloc(void)
Definition: packet-queue.c:221
PacketQueueFree
void PacketQueueFree(PacketQueue *pq)
Definition: packet-queue.c:231
suricata.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCMutexDestroy
#define SCMutexDestroy
Definition: threads-debug.h:120
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102