suricata
flow-queue.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2020 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 * Flow queue handler functions
24 */
25
26#include "suricata-common.h"
27#include "threads.h"
28#include "flow-private.h"
29#include "flow-queue.h"
30#include "flow-util.h"
31#include "util-error.h"
32#include "util-debug.h"
33#include "util-print.h"
34
36{
37 FlowQueue *q = (FlowQueue *)SCMalloc(sizeof(FlowQueue));
38 if (q == NULL) {
39 SCLogError("Fatal error encountered in FlowQueueNew. Exiting...");
40 exit(EXIT_SUCCESS);
41 }
42 q = FlowQueueInit(q);
43 return q;
44}
45
47{
48 if (q != NULL) {
49 memset(q, 0, sizeof(FlowQueue));
50 FQLOCK_INIT(q);
51 }
52 return q;
53}
54
55/**
56 * \brief Destroy a flow queue
57 *
58 * \param q the flow queue to destroy
59 */
61{
63}
64
66{
67 if (fqc->top == NULL) {
68 fqc->top = fqc->bot = f;
69 fqc->len = 1;
70 } else {
71 fqc->bot->next = f;
72 fqc->bot = f;
73 fqc->len++;
74 }
75 f->next = NULL;
76}
77
79{
80 f->next = fqc->top;
81 fqc->top = f;
82 if (f->next == NULL) {
83 fqc->bot = f;
84 }
85 fqc->len++;
86}
87
89{
90 if (src->top == NULL)
91 return;
92
93 if (dest->bot == NULL) {
94 dest->top = src->top;
95 dest->bot = src->bot;
96 dest->len = src->len;
97 } else {
98 dest->bot->next = src->top;
99 dest->bot = src->bot;
100 dest->len += src->len;
101 }
102 src->top = src->bot = NULL;
103 src->len = 0;
104}
105
106static inline void FlowQueueAtomicSetNonEmpty(FlowQueue *fq)
107{
108 if (!SC_ATOMIC_GET(fq->non_empty)) {
109 SC_ATOMIC_SET(fq->non_empty, true);
110 }
111}
112static inline void FlowQueueAtomicSetEmpty(FlowQueue *fq)
113{
114 if (SC_ATOMIC_GET(fq->non_empty)) {
115 SC_ATOMIC_SET(fq->non_empty, false);
116 }
117}
118
120{
121 if (fqc->top == NULL)
122 return;
123
124 FQLOCK_LOCK(fq);
125 if (fq->qbot == NULL) {
126 fq->qtop = fqc->top;
127 fq->qbot = fqc->bot;
128 fq->qlen = fqc->len;
129 } else {
130 fq->qbot->next = fqc->top;
131 fq->qbot = fqc->bot;
132 fq->qlen += fqc->len;
133 }
134 FlowQueueAtomicSetNonEmpty(fq);
135 FQLOCK_UNLOCK(fq);
136 fqc->top = fqc->bot = NULL;
137 fqc->len = 0;
138}
139
141{
142 FQLOCK_LOCK(fq);
143 FlowQueuePrivate fqc = fq->priv;
144 fq->qtop = fq->qbot = NULL;
145 fq->qlen = 0;
146 FlowQueueAtomicSetEmpty(fq);
147 FQLOCK_UNLOCK(fq);
148 return fqc;
149}
150
152{
153 Flow *f = fqc->top;
154 if (f == NULL) {
155 return NULL;
156 }
157
158 fqc->top = f->next;
159 f->next = NULL;
160 fqc->len--;
161 if (fqc->top == NULL) {
162 fqc->bot = NULL;
163 }
164 return f;
165}
166
167/**
168 * \brief add a flow to a queue
169 *
170 * \param q queue
171 * \param f flow
172 */
174{
175#ifdef DEBUG
176 BUG_ON(q == NULL || f == NULL);
177#endif
178 FQLOCK_LOCK(q);
180 FlowQueueAtomicSetNonEmpty(q);
181 FQLOCK_UNLOCK(q);
182}
183
184/**
185 * \brief remove a flow from the queue
186 *
187 * \param q queue
188 *
189 * \retval f flow or NULL if empty list.
190 */
192{
193 FQLOCK_LOCK(q);
195 if (f == NULL)
196 FlowQueueAtomicSetEmpty(q);
197 FQLOCK_UNLOCK(q);
198 return f;
199}
uint16_t src
void FlowQueuePrivatePrependFlow(FlowQueuePrivate *fqc, Flow *f)
Definition flow-queue.c:78
void FlowQueuePrivateAppendFlow(FlowQueuePrivate *fqc, Flow *f)
Definition flow-queue.c:65
FlowQueue * FlowQueueNew(void)
Definition flow-queue.c:35
Flow * FlowQueuePrivateGetFromTop(FlowQueuePrivate *fqc)
Definition flow-queue.c:151
void FlowQueueAppendPrivate(FlowQueue *fq, FlowQueuePrivate *fqc)
Definition flow-queue.c:119
Flow * FlowDequeue(FlowQueue *q)
remove a flow from the queue
Definition flow-queue.c:191
FlowQueuePrivate FlowQueueExtractPrivate(FlowQueue *fq)
Definition flow-queue.c:140
FlowQueue * FlowQueueInit(FlowQueue *q)
Definition flow-queue.c:46
void FlowEnqueue(FlowQueue *q, Flow *f)
add a flow to a queue
Definition flow-queue.c:173
void FlowQueuePrivateAppendPrivate(FlowQueuePrivate *dest, FlowQueuePrivate *src)
Definition flow-queue.c:88
void FlowQueueDestroy(FlowQueue *q)
Destroy a flow queue.
Definition flow-queue.c:60
#define FQLOCK_INIT(q)
Definition flow-queue.h:70
#define FQLOCK_LOCK(q)
Definition flow-queue.h:72
#define FQLOCK_DESTROY(q)
Definition flow-queue.h:71
#define FQLOCK_UNLOCK(q)
Definition flow-queue.h:74
FlowQueuePrivate priv
Definition flow-queue.h:49
Flow data structure.
Definition flow.h:356
struct Flow_ * next
Definition flow.h:396
#define BUG_ON(x)
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCMalloc(sz)
Definition util-mem.h:47