1 /* Copyright (C) 2007-2012 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 * Defrag tracker queue handler functions
24 */
25
26 #include "suricata-common.h"
27 #include "threads.h"
28 #include "debug.h"
29 #include "defrag-queue.h"
30 #include "util-error.h"
31 #include "util-debug.h"
32 #include "util-print.h"
33
DefragTrackerQueueInit(DefragTrackerQueue * q)34 DefragTrackerQueue *DefragTrackerQueueInit (DefragTrackerQueue *q)
35 {
36 if (q != NULL) {
37 memset(q, 0, sizeof(DefragTrackerQueue));
38 DQLOCK_INIT(q);
39 }
40 return q;
41 }
42
DefragTrackerQueueNew()43 DefragTrackerQueue *DefragTrackerQueueNew()
44 {
45 DefragTrackerQueue *q = (DefragTrackerQueue *)SCMalloc(sizeof(DefragTrackerQueue));
46 if (q == NULL) {
47 SCLogError(SC_ERR_FATAL, "Fatal error encountered in DefragTrackerQueueNew. Exiting...");
48 exit(EXIT_SUCCESS);
49 }
50 q = DefragTrackerQueueInit(q);
51 return q;
52 }
53
54 /**
55 * \brief Destroy a tracker queue
56 *
57 * \param q the tracker queue to destroy
58 */
DefragTrackerQueueDestroy(DefragTrackerQueue * q)59 void DefragTrackerQueueDestroy (DefragTrackerQueue *q)
60 {
61 DQLOCK_DESTROY(q);
62 }
63
64 /**
65 * \brief add a tracker to a queue
66 *
67 * \param q queue
68 * \param dt tracker
69 */
DefragTrackerEnqueue(DefragTrackerQueue * q,DefragTracker * dt)70 void DefragTrackerEnqueue (DefragTrackerQueue *q, DefragTracker *dt)
71 {
72 #ifdef DEBUG
73 BUG_ON(q == NULL || dt == NULL);
74 #endif
75
76 DQLOCK_LOCK(q);
77
78 /* more trackers in queue */
79 if (q->top != NULL) {
80 dt->lnext = q->top;
81 q->top->lprev = dt;
82 q->top = dt;
83 /* only tracker */
84 } else {
85 q->top = dt;
86 q->bot = dt;
87 }
88 q->len++;
89 #ifdef DBG_PERF
90 if (q->len > q->dbg_maxlen)
91 q->dbg_maxlen = q->len;
92 #endif /* DBG_PERF */
93 DQLOCK_UNLOCK(q);
94 }
95
96 /**
97 * \brief remove a tracker from the queue
98 *
99 * \param q queue
100 *
101 * \retval dt tracker or NULL if empty list.
102 */
DefragTrackerDequeue(DefragTrackerQueue * q)103 DefragTracker *DefragTrackerDequeue (DefragTrackerQueue *q)
104 {
105 DQLOCK_LOCK(q);
106
107 DefragTracker *dt = q->bot;
108 if (dt == NULL) {
109 DQLOCK_UNLOCK(q);
110 return NULL;
111 }
112
113 /* more packets in queue */
114 if (q->bot->lprev != NULL) {
115 q->bot = q->bot->lprev;
116 q->bot->lnext = NULL;
117 /* just the one we remove, so now empty */
118 } else {
119 q->top = NULL;
120 q->bot = NULL;
121 }
122
123 #ifdef DEBUG
124 BUG_ON(q->len == 0);
125 #endif
126 if (q->len > 0)
127 q->len--;
128
129 dt->lnext = NULL;
130 dt->lprev = NULL;
131
132 DQLOCK_UNLOCK(q);
133 return dt;
134 }
135
DefragTrackerQueueLen(DefragTrackerQueue * q)136 uint32_t DefragTrackerQueueLen(DefragTrackerQueue *q)
137 {
138 uint32_t len;
139 DQLOCK_LOCK(q);
140 len = q->len;
141 DQLOCK_UNLOCK(q);
142 return len;
143 }
144
145