suricata
packet-queue.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 
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  Packet *p = NULL;
170 
171  //PacketQueueValidateDebug(q);
172  /* if the queue is empty there are no packets left. */
173  if (q->len == 0) {
174  return NULL;
175  }
176 
177  q->len--;
178 
179  /* pull the bottom packet from the queue */
180  p = q->bot;
181 
182  /* Weird issue: sometimes it looks that two thread arrive
183  * here at the same time so the bot ptr is NULL (only on OS X?)
184  */
185  BUG_ON (p == NULL);
186 
187  /* more packets in queue */
188  if (q->bot->prev != NULL) {
189  q->bot = q->bot->prev;
190  q->bot->next = NULL;
191  /* just the one we remove, so now empty */
192  } else {
193  q->top = NULL;
194  q->bot = NULL;
195  }
196 
197  //PacketQueueValidateDebug(q);
198  p->next = NULL;
199  p->prev = NULL;
200  return p;
201 }
202 
#define SCLogDebug(...)
Definition: util-debug.h:335
#define BUG_ON(x)
struct Packet_ * next
Definition: decode.h:570
uint32_t len
Definition: decode.h:623
Packet * top
Definition: decode.h:621
Packet * bot
Definition: decode.h:622
struct Packet_ * prev
Definition: decode.h:571
Packet * PacketDequeue(PacketQueue *q)
Definition: packet-queue.c:167
void PacketEnqueue(PacketQueue *q, Packet *p)
Definition: packet-queue.c:139