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 
34 #ifdef DEBUG
35 void PacketQueueValidateDebug(PacketQueue *q);
36 void PacketQueueValidate(PacketQueue *q);
37 
38 void PacketQueueValidateDebug(PacketQueue *q)
39 {
40  SCLogDebug("q->len %u, q->top %p, q->bot %p", q->len, q->top, q->bot);
41 
42  if (q->len == 0) {
43  BUG_ON(q->top != NULL);
44  BUG_ON(q->bot != NULL);
45  } else if(q->len == 1) {
46  SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev);
47  SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev);
48 
49  BUG_ON(q->top != q->bot);
50  BUG_ON(q->top->next != NULL);
51  BUG_ON(q->bot->next != NULL);
52  BUG_ON(q->top->prev != NULL);
53  BUG_ON(q->bot->prev != NULL);
54  } else if (q->len == 2) {
55  SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev);
56  SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev);
57 
58  BUG_ON(q->top == NULL);
59  BUG_ON(q->bot == NULL);
60 
61  BUG_ON(q->top == q->bot);
62 
63  BUG_ON(q->top->prev != NULL);
64  BUG_ON(q->top->next != q->bot);
65 
66  BUG_ON(q->bot->prev != q->top);
67  BUG_ON(q->bot->next != NULL);
68  } else {
69  BUG_ON(q->top == NULL);
70  BUG_ON(q->bot == NULL);
71 
72  SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev);
73  SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev);
74 
75  BUG_ON(q->top == q->bot);
76  BUG_ON(q->top->prev != NULL);
77  BUG_ON(q->bot->next != NULL);
78 
79  BUG_ON(q->top->next == q->bot);
80  BUG_ON(q->bot->prev == q->top);
81 
82  Packet *p, *pp;
83  for (p = q->top, pp = p->prev; p != NULL; pp = p, p = p->next) {
84  SCLogDebug("p %p, pp %p, p->next %p, p->prev %p", p, pp, p->next, p->prev);
85  BUG_ON(pp != p->prev);
86  }
87 
88  }
89 }
90 
91 #define BUGGER_ON(cond) { \
92  if ((cond)) { \
93  PacketQueueValidateDebug(q); \
94  } \
95 }
96 
97 void PacketQueueValidate(PacketQueue *q)
98 {
99  if (q->len == 0) {
100  BUGGER_ON(q->top != NULL);
101  BUGGER_ON(q->bot != NULL);
102  } else if(q->len == 1) {
103  BUGGER_ON(q->top != q->bot);
104  BUGGER_ON(q->top->next != NULL);
105  BUGGER_ON(q->bot->next != NULL);
106  BUGGER_ON(q->top->prev != NULL);
107  BUGGER_ON(q->bot->prev != NULL);
108  } else if (q->len == 2) {
109  BUGGER_ON(q->top == NULL);
110  BUGGER_ON(q->bot == NULL);
111 
112  BUGGER_ON(q->top == q->bot);
113 
114  BUGGER_ON(q->top->prev != NULL);
115  BUGGER_ON(q->top->next != q->bot);
116 
117  BUGGER_ON(q->bot->prev != q->top);
118  BUGGER_ON(q->bot->next != NULL);
119  } else {
120  BUGGER_ON(q->top == NULL);
121  BUGGER_ON(q->bot == NULL);
122 
123  BUGGER_ON(q->top == q->bot);
124  BUGGER_ON(q->top->prev != NULL);
125  BUGGER_ON(q->bot->next != NULL);
126 
127  BUGGER_ON(q->top->next == q->bot);
128  BUGGER_ON(q->bot->prev == q->top);
129 
130  Packet *p, *pp;
131  for (p = q->top, pp = p->prev; p != NULL; pp = p, p = p->next) {
132  BUGGER_ON(pp != p->prev);
133  }
134 
135  }
136 }
137 #endif /* DEBUG */
138 
139 static inline void PacketEnqueueDo(PacketQueue *q, Packet *p)
140 {
141  //PacketQueueValidateDebug(q);
142 
143  if (p == NULL)
144  return;
145 
146  /* more packets in queue */
147  if (q->top != NULL) {
148  p->prev = NULL;
149  p->next = q->top;
150  q->top->prev = p;
151  q->top = p;
152  /* only packet */
153  } else {
154  p->prev = NULL;
155  p->next = NULL;
156  q->top = p;
157  q->bot = p;
158  }
159  q->len++;
160 #ifdef DBG_PERF
161  if (q->len > q->dbg_maxlen)
162  q->dbg_maxlen = q->len;
163 #endif /* DBG_PERF */
164  //PacketQueueValidateDebug(q);
165 }
166 
168 {
169  PacketQueue *q = (PacketQueue *)qnl;
170  PacketEnqueueDo(q, p);
171 }
172 
174 {
175  PacketEnqueueDo(q, p);
176 }
177 
178 static inline Packet *PacketDequeueDo (PacketQueue *q)
179 {
180  //PacketQueueValidateDebug(q);
181  /* if the queue is empty there are no packets left. */
182  if (q->len == 0) {
183  return NULL;
184  }
185  q->len--;
186 
187  /* pull the bottom packet from the queue */
188  Packet *p = q->bot;
189 
190  /* more packets in queue */
191  if (q->bot->prev != NULL) {
192  q->bot = q->bot->prev;
193  q->bot->next = NULL;
194  /* just the one we remove, so now empty */
195  } else {
196  q->top = NULL;
197  q->bot = NULL;
198  }
199 
200  //PacketQueueValidateDebug(q);
201  p->next = NULL;
202  p->prev = NULL;
203  return p;
204 }
205 
207 {
208  PacketQueue *q = (PacketQueue *)qnl;
209  return PacketDequeueDo(q);
210 }
211 
213 {
214  return PacketDequeueDo(q);
215 }
216 
218 {
219  PacketQueue *pq = SCCalloc(1, sizeof(*pq));
220  if (pq == NULL)
221  return NULL;
222  SCMutexInit(&pq->mutex_q, NULL);
223  SCCondInit(&pq->cond_q, NULL);
224  return pq;
225 }
226 
228 {
229  SCCondDestroy(&pq->cond_q);
230  SCMutexDestroy(&pq->mutex_q);
231  SCFree(pq);
232 }
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
PacketEnqueue
void PacketEnqueue(PacketQueue *q, Packet *p)
Definition: packet-queue.c:173
PacketQueue_
simple fifo queue for packets with mutex and cond Calling the mutex or triggering the cond is respons...
Definition: packet-queue.h:47
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:32
PacketQueue_::mutex_q
SCMutex mutex_q
Definition: packet-queue.h:54
decode.h
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:206
Packet_::prev
struct Packet_ * prev
Definition: decode.h:574
pkt-var.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:282
Packet_
Definition: decode.h:411
PacketQueue_::bot
struct Packet_ * bot
Definition: packet-queue.h:49
PacketQueue_::cond_q
SCCondT cond_q
Definition: packet-queue.h:55
SCMutexInit
#define SCMutexInit(mut, mutattrs)
Definition: threads-debug.h:116
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:167
suricata-common.h
PacketQueue_::len
uint32_t len
Definition: packet-queue.h:50
PacketDequeue
Packet * PacketDequeue(PacketQueue *q)
Definition: packet-queue.c:212
Packet_::next
struct Packet_ * next
Definition: decode.h:573
PacketQueue_::top
struct Packet_ * top
Definition: packet-queue.h:48
SCCondDestroy
#define SCCondDestroy
Definition: threads-debug.h:140
SCFree
#define SCFree(p)
Definition: util-mem.h:61
PacketQueueAlloc
PacketQueue * PacketQueueAlloc(void)
Definition: packet-queue.c:217
PacketQueueFree
void PacketQueueFree(PacketQueue *pq)
Definition: packet-queue.c:227
suricata.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCMutexDestroy
#define SCMutexDestroy
Definition: threads-debug.h:120